hydrus/client.py

206 lines
5.8 KiB
Python
Raw Normal View History

2019-01-09 22:59:03 +00:00
#!/usr/bin/env python3
2016-10-26 20:45:34 +00:00
# This program is free software. It comes without any warranty, to
# the extent permitted by applicable law. You can redistribute it
# and/or modify it under the terms of the Do What The Fuck You Want
# To Public License, Version 2, as published by Sam Hocevar. See
# http://sam.zoy.org/wtfpl/COPYING for more details.
try:
2019-01-09 22:59:03 +00:00
from include import HydrusPy2To3
2019-01-23 22:19:16 +00:00
import wx
HydrusPy2To3.do_2to3_test( wx_error_display_callable = wx.SafeShowMessage )
2019-01-09 22:59:03 +00:00
2016-10-26 20:45:34 +00:00
from include import HydrusExceptions
from include import HydrusConstants as HC
from include import HydrusData
from include import HydrusPaths
import os
import sys
import time
from include import ClientController
import threading
2017-05-10 21:33:58 +00:00
from include import HydrusGlobals as HG
2016-10-26 20:45:34 +00:00
from include import HydrusLogger
import traceback
2017-10-25 21:45:15 +00:00
try:
from twisted.internet import reactor
except:
HG.twisted_is_broke = True
2016-10-26 20:45:34 +00:00
#
import argparse
argparser = argparse.ArgumentParser( description = 'hydrus network client (console)' )
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' )
2016-10-26 20:45:34 +00:00
argparser.add_argument( '--no_daemons', action='store_true', help = 'run without background daemons' )
2019-09-18 22:40:39 +00:00
argparser.add_argument( '--no_wal', action='store_true', help = 'run without WAL db journaling' )
argparser.add_argument( '--db_memory_journaling', action='store_true', help = 'run db journaling entirely in memory (DANGEROUS)' )
2019-09-11 21:51:09 +00:00
argparser.add_argument( '--db_synchronous_override', help = 'override SQLite Synchronous PRAGMA (range 0-3, default=2)' )
argparser.add_argument( '--no_db_temp_files', action='store_true', help = 'run db temp operations entirely in memory' )
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-01-09 22:59:03 +00:00
if not HydrusPaths.DirectoryIsWritable( db_dir ) or HC.RUNNING_FROM_OSX_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
HG.no_wal = result.no_wal
2019-09-18 22:40:39 +00:00
HG.db_memory_journaling = result.db_memory_journaling
2019-09-11 21:51:09 +00:00
if result.db_synchronous_override is not None:
try:
db_synchronous_override = int( result.db_synchronous_override )
except ValueError:
raise Exception( 'db_synchronous_override must be an integer in the range 0-3' )
if db_synchronous_override not in range( 4 ):
raise Exception( 'db_synchronous_override must be in the range 0-3' )
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
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
except Exception as e:
import traceback
import os
error_trace = traceback.format_exc()
print( error_trace )
wx.SafeShowMessage( 'critical boot error!', 'Critical boot error occurred! Details written to crash.log!' + os.linesep * 2 + str( e ) )
if 'db_dir' in locals() and os.path.exists( db_dir ):
dest_path = os.path.join( db_dir, 'crash.log' )
with open( dest_path, 'w', encoding = 'utf-8' ) as f:
2019-03-20 21:22:10 +00:00
2019-06-05 19:42:39 +00:00
f.write( error_trace )
2019-03-20 21:22:10 +00:00
2019-06-05 19:42:39 +00:00
print( 'Critical boot error occurred! Details written to crash.log!' )
2019-03-20 21:22:10 +00:00
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-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
controller = ClientController.Controller( db_dir )
controller.Run()
except:
HydrusData.Print( 'hydrus client failed' )
HydrusData.Print( traceback.format_exc() )
try:
2016-10-26 20:45:34 +00:00
2019-06-05 19:42:39 +00:00
message = 'The client failed to start. The error follows (it has also been written to the log in the db directory). If it is not obvious, please inform hydrus dev.'
2016-10-26 20:45:34 +00:00
2019-06-05 19:42:39 +00:00
message += os.linesep * 2
2016-10-26 20:45:34 +00:00
2019-06-05 19:42:39 +00:00
message += traceback.format_exc()
2016-10-26 20:45:34 +00:00
2019-06-05 19:42:39 +00:00
wx.SafeShowMessage( 'hydrus client failed', message )
2016-10-26 20:45:34 +00:00
2019-06-05 19:42:39 +00:00
except:
2016-10-26 20:45:34 +00:00
2019-06-05 19:42:39 +00:00
pass
2016-10-26 20:45:34 +00:00
2019-06-05 19:42:39 +00:00
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-06-05 19:42:39 +00:00
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