2019-01-09 22:59:03 +00:00
|
|
|
#!/usr/bin/env python3
|
2016-10-26 20:45:34 +00:00
|
|
|
|
2019-11-14 03:56:30 +00:00
|
|
|
# Hydrus is released under WTFPL
|
|
|
|
# You just DO WHAT THE FUCK YOU WANT TO.
|
|
|
|
# https://github.com/sirkris/WTFPL/blob/master/WTFPL.md
|
2016-10-26 20:45:34 +00:00
|
|
|
|
|
|
|
try:
|
|
|
|
|
2019-11-14 03:56:30 +00:00
|
|
|
import locale
|
2019-01-09 22:59:03 +00:00
|
|
|
|
2019-11-14 03:56:30 +00:00
|
|
|
try: locale.setlocale( locale.LC_ALL, '' )
|
|
|
|
except: pass
|
2019-01-23 22:19:16 +00:00
|
|
|
|
2019-11-14 03:56:30 +00:00
|
|
|
import os
|
2016-10-26 20:45:34 +00:00
|
|
|
import argparse
|
2020-04-22 21:00:35 +00:00
|
|
|
import traceback
|
|
|
|
|
2020-07-08 22:00:33 +00:00
|
|
|
from hydrus.core import HydrusBoot
|
|
|
|
|
|
|
|
HydrusBoot.AddBaseDirToEnvPath()
|
|
|
|
|
2020-04-22 21:00:35 +00:00
|
|
|
# initialise Qt here, important it is done early
|
|
|
|
from hydrus.client.gui import QtPorting as QP
|
|
|
|
|
|
|
|
from hydrus.core import HydrusConstants as HC
|
|
|
|
from hydrus.core import HydrusPaths
|
|
|
|
from hydrus.core import HydrusGlobals as HG
|
2016-10-26 20:45:34 +00:00
|
|
|
|
2019-11-20 23:10:46 +00:00
|
|
|
argparser = argparse.ArgumentParser( description = 'hydrus network client (console)' )
|
2016-10-26 20:45:34 +00:00
|
|
|
|
|
|
|
argparser.add_argument( '-d', '--db_dir', help = 'set an external db location' )
|
2019-09-11 21:51:09 +00:00
|
|
|
argparser.add_argument( '--temp_dir', help = 'override the program\'s temporary directory' )
|
2020-12-09 22:18:48 +00:00
|
|
|
argparser.add_argument( '--db_journal_mode', default = 'WAL', choices = [ 'WAL', 'TRUNCATE', 'PERSIST', 'MEMORY' ], help = 'change db journal mode (default=WAL)' )
|
2020-12-23 23:07:58 +00:00
|
|
|
argparser.add_argument( '--db_cache_size', type = int, help = 'override SQLite cache_size per db file, in MB (default=200)' )
|
2020-12-16 22:29:51 +00:00
|
|
|
argparser.add_argument( '--db_synchronous_override', type = int, choices = range(4), help = 'override SQLite Synchronous PRAGMA (default=2)' )
|
2019-09-11 21:51:09 +00:00
|
|
|
argparser.add_argument( '--no_db_temp_files', action='store_true', help = 'run db temp operations entirely in memory' )
|
2020-12-16 22:29:51 +00:00
|
|
|
argparser.add_argument( '--boot_debug', action='store_true', help = 'print additional bootup information to the log' )
|
2020-12-09 22:18:48 +00:00
|
|
|
argparser.add_argument( '--no_daemons', action='store_true', help = 'run without background daemons' )
|
|
|
|
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)' )
|
2016-10-26 20:45:34 +00:00
|
|
|
|
|
|
|
result = argparser.parse_args()
|
|
|
|
|
|
|
|
if result.db_dir is None:
|
|
|
|
|
2017-01-18 22:52:39 +00:00
|
|
|
db_dir = HC.DEFAULT_DB_DIR
|
2016-10-26 20:45:34 +00:00
|
|
|
|
2019-11-20 23:10:46 +00:00
|
|
|
if not HydrusPaths.DirectoryIsWritable( db_dir ) or HC.RUNNING_FROM_MACOS_APP:
|
2018-02-21 21:59:37 +00:00
|
|
|
|
2019-01-09 22:59:03 +00:00
|
|
|
db_dir = HC.USERPATH_DB_DIR
|
2018-02-21 21:59:37 +00:00
|
|
|
|
|
|
|
|
2016-10-26 20:45:34 +00:00
|
|
|
else:
|
|
|
|
|
|
|
|
db_dir = result.db_dir
|
|
|
|
|
|
|
|
|
|
|
|
db_dir = HydrusPaths.ConvertPortablePathToAbsPath( db_dir, HC.BASE_DIR )
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
|
|
|
HydrusPaths.MakeSureDirectoryExists( db_dir )
|
|
|
|
|
|
|
|
except:
|
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
raise Exception( 'Could not ensure db path "{}" exists! Check the location is correct and that you have permission to write to it!'.format( db_dir ) )
|
|
|
|
|
|
|
|
|
|
|
|
if not os.path.isdir( db_dir ):
|
|
|
|
|
|
|
|
raise Exception( 'The given db path "{}" is not a directory!'.format( db_dir ) )
|
|
|
|
|
|
|
|
|
|
|
|
if not HydrusPaths.DirectoryIsWritable( db_dir ):
|
|
|
|
|
|
|
|
raise Exception( 'The given db path "{}" is not a writable-to!'.format( db_dir ) )
|
2016-10-26 20:45:34 +00:00
|
|
|
|
|
|
|
|
2019-03-20 21:22:10 +00:00
|
|
|
HG.no_daemons = result.no_daemons
|
2020-12-09 22:18:48 +00:00
|
|
|
|
|
|
|
HG.db_journal_mode = result.db_journal_mode
|
|
|
|
|
|
|
|
if result.no_wal:
|
|
|
|
|
|
|
|
HG.db_journal_mode = 'TRUNCATE'
|
|
|
|
|
|
|
|
if result.db_memory_journaling:
|
|
|
|
|
|
|
|
HG.db_journal_mode = 'MEMORY'
|
|
|
|
|
2019-09-11 21:51:09 +00:00
|
|
|
|
2020-12-23 23:07:58 +00:00
|
|
|
if result.db_cache_size is not None:
|
|
|
|
|
|
|
|
HG.db_cache_size = result.db_cache_size
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
HG.db_cache_size = 200
|
|
|
|
|
|
|
|
|
2019-09-11 21:51:09 +00:00
|
|
|
if result.db_synchronous_override is not None:
|
|
|
|
|
2020-12-09 22:18:48 +00:00
|
|
|
HG.db_synchronous = int( result.db_synchronous_override )
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
if HG.db_journal_mode == 'WAL':
|
2019-09-11 21:51:09 +00:00
|
|
|
|
2020-12-09 22:18:48 +00:00
|
|
|
HG.db_synchronous = 1
|
2019-09-11 21:51:09 +00:00
|
|
|
|
2020-12-09 22:18:48 +00:00
|
|
|
else:
|
2019-09-11 21:51:09 +00:00
|
|
|
|
2020-12-09 22:18:48 +00:00
|
|
|
HG.db_synchronous = 2
|
2019-09-11 21:51:09 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
2019-03-06 23:06:22 +00:00
|
|
|
HG.no_db_temp_files = result.no_db_temp_files
|
2016-10-26 20:45:34 +00:00
|
|
|
|
2020-12-16 22:29:51 +00:00
|
|
|
HG.boot_debug = result.boot_debug
|
|
|
|
|
2019-03-20 21:22:10 +00:00
|
|
|
if result.temp_dir is not None:
|
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
HydrusPaths.SetEnvTempDir( result.temp_dir )
|
2019-03-20 21:22:10 +00:00
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
|
2020-04-22 21:00:35 +00:00
|
|
|
from hydrus.core import HydrusData
|
|
|
|
from hydrus.core import HydrusLogger
|
2019-06-05 19:42:39 +00:00
|
|
|
|
2019-11-14 03:56:30 +00:00
|
|
|
try:
|
|
|
|
|
|
|
|
from twisted.internet import reactor
|
|
|
|
|
|
|
|
except:
|
|
|
|
|
|
|
|
HG.twisted_is_broke = True
|
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
|
2019-11-14 03:56:30 +00:00
|
|
|
except Exception as e:
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
2020-04-22 21:00:35 +00:00
|
|
|
from hydrus.core import HydrusData
|
2019-11-14 03:56:30 +00:00
|
|
|
|
|
|
|
HydrusData.DebugPrint( 'Critical boot error occurred! Details written to crash.log!' )
|
|
|
|
HydrusData.PrintException( e )
|
|
|
|
|
|
|
|
except:
|
|
|
|
|
|
|
|
pass
|
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
|
2019-11-20 23:10:46 +00:00
|
|
|
error_trace = traceback.format_exc()
|
|
|
|
|
|
|
|
print( error_trace )
|
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
if 'db_dir' in locals() and os.path.exists( db_dir ):
|
|
|
|
|
2019-11-20 23:10:46 +00:00
|
|
|
emergency_dir = db_dir
|
|
|
|
|
|
|
|
else:
|
|
|
|
|
|
|
|
emergency_dir = os.path.expanduser( '~' )
|
2019-11-14 03:56:30 +00:00
|
|
|
|
2019-11-20 23:10:46 +00:00
|
|
|
possible_desktop = os.path.join( emergency_dir, 'Desktop' )
|
2019-06-05 19:42:39 +00:00
|
|
|
|
2019-11-20 23:10:46 +00:00
|
|
|
if os.path.exists( possible_desktop ) and os.path.isdir( possible_desktop ):
|
2019-03-20 21:22:10 +00:00
|
|
|
|
2019-11-20 23:10:46 +00:00
|
|
|
emergency_dir = possible_desktop
|
2019-03-20 21:22:10 +00:00
|
|
|
|
|
|
|
|
2019-11-20 23:10:46 +00:00
|
|
|
|
|
|
|
dest_path = os.path.join( emergency_dir, 'hydrus_crash.log' )
|
|
|
|
|
|
|
|
with open( dest_path, 'w', encoding = 'utf-8' ) as f:
|
|
|
|
|
|
|
|
f.write( error_trace )
|
2019-06-05 19:42:39 +00:00
|
|
|
|
2019-03-20 21:22:10 +00:00
|
|
|
|
2019-11-20 23:10:46 +00:00
|
|
|
print( 'Critical boot error occurred! Details written to hydrus_crash.log in either db dir or user dir!' )
|
|
|
|
|
|
|
|
import sys
|
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
sys.exit( 1 )
|
|
|
|
|
2019-08-15 00:40:48 +00:00
|
|
|
controller = None
|
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
with HydrusLogger.HydrusLogger( db_dir, 'client' ) as logger:
|
2016-10-26 20:45:34 +00:00
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
try:
|
2016-10-26 20:45:34 +00:00
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
HydrusData.Print( 'hydrus client started' )
|
|
|
|
|
|
|
|
if not HG.twisted_is_broke:
|
2016-10-26 20:45:34 +00:00
|
|
|
|
2019-11-14 03:56:30 +00:00
|
|
|
import threading
|
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
threading.Thread( target = reactor.run, name = 'twisted', kwargs = { 'installSignalHandlers' : 0 } ).start()
|
2016-10-26 20:45:34 +00:00
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
|
2020-04-22 21:00:35 +00:00
|
|
|
from hydrus.client import ClientController
|
2019-11-14 03:56:30 +00:00
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
controller = ClientController.Controller( db_dir )
|
|
|
|
|
|
|
|
controller.Run()
|
|
|
|
|
|
|
|
except:
|
|
|
|
|
|
|
|
HydrusData.Print( 'hydrus client failed' )
|
|
|
|
|
|
|
|
HydrusData.Print( traceback.format_exc() )
|
|
|
|
|
|
|
|
finally:
|
|
|
|
|
|
|
|
HG.view_shutdown = True
|
|
|
|
HG.model_shutdown = True
|
|
|
|
|
2019-08-15 00:40:48 +00:00
|
|
|
if controller is not None:
|
2016-10-26 20:45:34 +00:00
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
controller.pubimmediate( 'wake_daemons' )
|
2016-10-26 20:45:34 +00:00
|
|
|
|
|
|
|
|
2019-11-14 03:56:30 +00:00
|
|
|
if not HG.twisted_is_broke:
|
|
|
|
|
|
|
|
reactor.callFromThread( reactor.stop )
|
|
|
|
|
2016-10-26 20:45:34 +00:00
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
HydrusData.Print( 'hydrus client shut down' )
|
2016-10-26 20:45:34 +00:00
|
|
|
|
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
HG.shutdown_complete = True
|
|
|
|
|
|
|
|
if HG.restart:
|
2016-10-26 20:45:34 +00:00
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
HydrusData.RestartProcess()
|
2017-01-18 22:52:39 +00:00
|
|
|
|
2019-06-05 19:42:39 +00:00
|
|
|
|