hydrus/server.py

214 lines
6.0 KiB
Python
Raw Normal View History

2019-01-09 22:59:03 +00:00
#!/usr/bin/env python3
2015-11-25 22:00:57 +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
2015-09-02 23:16:09 +00:00
try:
2019-01-09 22:59:03 +00:00
from include import HydrusPy2To3
HydrusPy2To3.do_2to3_test()
2015-09-02 23:16:09 +00:00
import locale
try: locale.setlocale( locale.LC_ALL, '' )
except: pass
2015-11-18 22:44:07 +00:00
from include import HydrusExceptions
2015-09-02 23:16:09 +00:00
from include import HydrusConstants as HC
2015-11-18 22:44:07 +00:00
from include import HydrusData
2016-10-12 21:52:50 +00:00
from include import HydrusPaths
2015-09-02 23:16:09 +00:00
import os
import sys
import time
from include import ServerController
import threading
from twisted.internet import reactor
2017-05-10 21:33:58 +00:00
from include import HydrusGlobals as HG
2015-11-11 21:20:41 +00:00
from include import HydrusLogger
2015-09-02 23:16:09 +00:00
import traceback
2016-10-19 20:02:56 +00:00
#
2016-10-12 21:52:50 +00:00
import argparse
2015-09-02 23:16:09 +00:00
2016-10-12 21:52:50 +00:00
argparser = argparse.ArgumentParser( description = 'hydrus network server' )
2015-09-02 23:16:09 +00:00
2016-10-12 21:52:50 +00:00
argparser.add_argument( 'action', default = 'start', nargs = '?', choices = [ 'start', 'stop', 'restart' ], help = 'either start this server (default), or stop an existing server, or both' )
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-19 20:02:56 +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-12 21:52:50 +00:00
result = argparser.parse_args()
2016-10-19 20:02:56 +00:00
action = result.action
2016-10-12 21:52:50 +00:00
if result.db_dir is None:
2017-01-18 22:52:39 +00:00
db_dir = HC.DEFAULT_DB_DIR
2015-09-02 23:16:09 +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
2015-09-02 23:16:09 +00:00
else:
2016-10-12 21:52:50 +00:00
db_dir = result.db_dir
2016-10-26 20:45:34 +00:00
db_dir = HydrusPaths.ConvertPortablePathToAbsPath( db_dir, HC.BASE_DIR )
2016-10-19 20:02:56 +00:00
2016-10-12 21:52:50 +00:00
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-06-15 18:59:44 +00:00
2016-10-12 21:52:50 +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-19 20:02:56 +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
2016-10-19 20:02:56 +00:00
#
action = ServerController.ProcessStartingAction( db_dir, action )
2016-10-12 21:52:50 +00:00
2019-10-16 20:47:55 +00:00
if action == 'exit':
sys.exit( 0 )
2016-10-12 21:52:50 +00:00
except Exception as e:
2015-09-02 23:16:09 +00:00
import traceback
2016-08-10 19:04:08 +00:00
import os
2015-09-02 23:16:09 +00:00
2019-11-20 23:10:46 +00:00
error_trace = traceback.format_exc()
print( error_trace )
2016-10-12 21:52:50 +00:00
if 'db_dir' in locals() and os.path.exists( db_dir ):
2016-07-20 19:57:10 +00:00
2019-11-20 23:10:46 +00:00
emergency_dir = db_dir
else:
emergency_dir = os.path.expanduser( '~' )
possible_desktop = os.path.join( emergency_dir, 'Desktop' )
2016-07-20 19:57:10 +00:00
2019-11-20 23:10:46 +00:00
if os.path.exists( possible_desktop ) and os.path.isdir( possible_desktop ):
2016-07-20 19:57:10 +00:00
2019-11-20 23:10:46 +00:00
emergency_dir = possible_desktop
2016-07-20 19:57: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-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
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, 'server' ) as logger:
try:
if action in ( 'stop', 'restart' ):
ServerController.ShutdownSiblingInstance( db_dir )
if action in ( 'start', 'restart' ):
HydrusData.Print( 'Initialising controller\u2026' )
threading.Thread( target = reactor.run, name = 'twisted', kwargs = { 'installSignalHandlers' : 0 } ).start()
controller = ServerController.Controller( db_dir )
controller.Run()
except ( HydrusExceptions.InsufficientCredentialsException, HydrusExceptions.ShutdownException ) as e:
error = str( e )
HydrusData.Print( error )
except:
error = traceback.format_exc()
HydrusData.Print( 'Hydrus server 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:
2019-07-31 22:01:02 +00:00
controller.pubimmediate( 'wake_daemons' )
2019-06-05 19:42:39 +00:00
reactor.callFromThread( reactor.stop )
2016-07-20 19:57:10 +00:00
2019-07-31 22:01:02 +00:00
HydrusData.Print( 'hydrus server shut down' )
2017-01-18 22:52:39 +00:00