mirror of
https://github.com/kovidgoyal/calibre.git
synced 2025-07-08 10:44:09 -04:00
calibre-server: Add --pidfile and --daemonize options
This commit is contained in:
parent
3f2e08ba67
commit
9c371377b6
@ -20,10 +20,10 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
import Image as PILImage
|
import Image as PILImage
|
||||||
|
|
||||||
from calibre.constants import __version__, __appname__
|
from calibre.constants import __version__, __appname__, iswindows
|
||||||
from calibre.utils.genshi.template import MarkupTemplate
|
from calibre.utils.genshi.template import MarkupTemplate
|
||||||
from calibre import fit_image, guess_type, prepare_string_for_xml, \
|
from calibre import fit_image, guess_type, prepare_string_for_xml, \
|
||||||
strftime as _strftime, prints
|
strftime as _strftime
|
||||||
from calibre.library import server_config as config
|
from calibre.library import server_config as config
|
||||||
from calibre.library.database2 import LibraryDatabase2, FIELD_MAP
|
from calibre.library.database2 import LibraryDatabase2, FIELD_MAP
|
||||||
from calibre.utils.config import config_dir
|
from calibre.utils.config import config_dir
|
||||||
@ -423,10 +423,8 @@ class LibraryServer(object):
|
|||||||
self.opts.port, {'path':'/stanza'})
|
self.opts.port, {'path':'/stanza'})
|
||||||
except:
|
except:
|
||||||
import traceback
|
import traceback
|
||||||
print 'Failed to start BonJour:'
|
cherrypy.log.error('Failed to start BonJour:')
|
||||||
cherrypy.log('Failed to start BonJour:')
|
cherrypy.log.error(traceback.format_exc())
|
||||||
cherrypy.log(traceback.format_exc())
|
|
||||||
traceback.print_exc()
|
|
||||||
cherrypy.engine.block()
|
cherrypy.engine.block()
|
||||||
except Exception, e:
|
except Exception, e:
|
||||||
self.exception = e
|
self.exception = e
|
||||||
@ -436,10 +434,8 @@ class LibraryServer(object):
|
|||||||
stop_zeroconf()
|
stop_zeroconf()
|
||||||
except:
|
except:
|
||||||
import traceback
|
import traceback
|
||||||
print 'Failed to stop BonJour:'
|
cherrypy.log.error('Failed to stop BonJour:')
|
||||||
cherrypy.log('Failed to stop BonJour:')
|
cherrypy.log.error(traceback.format_exc())
|
||||||
cherrypy.log(traceback.format_exc())
|
|
||||||
traceback.print_exc()
|
|
||||||
|
|
||||||
def exit(self):
|
def exit(self):
|
||||||
cherrypy.engine.exit()
|
cherrypy.engine.exit()
|
||||||
@ -472,7 +468,8 @@ class LibraryServer(object):
|
|||||||
return of.getvalue()
|
return of.getvalue()
|
||||||
except Exception, err:
|
except Exception, err:
|
||||||
import traceback
|
import traceback
|
||||||
traceback.print_exc()
|
cherrypy.log.error('Failed to generate cover:')
|
||||||
|
cherrypy.log.error(traceback.print_exc())
|
||||||
raise cherrypy.HTTPError(404, 'Failed to generate cover: %s'%err)
|
raise cherrypy.HTTPError(404, 'Failed to generate cover: %s'%err)
|
||||||
|
|
||||||
def get_format(self, id, format):
|
def get_format(self, id, format):
|
||||||
@ -813,7 +810,7 @@ class LibraryServer(object):
|
|||||||
# A better search would be great
|
# A better search would be great
|
||||||
want_mobile = self.MOBILE_UA.search(ua) is not None
|
want_mobile = self.MOBILE_UA.search(ua) is not None
|
||||||
if self.opts.develop and not want_mobile:
|
if self.opts.develop and not want_mobile:
|
||||||
prints('User agent:', ua)
|
cherrypy.log('User agent: '+ua)
|
||||||
|
|
||||||
if want_opds:
|
if want_opds:
|
||||||
return self.stanza(search=kwargs.get('search', None), sortby=kwargs.get('sortby',None), authorid=kwargs.get('authorid',None),
|
return self.stanza(search=kwargs.get('search', None), sortby=kwargs.get('sortby',None), authorid=kwargs.get('authorid',None),
|
||||||
@ -882,12 +879,55 @@ def option_parser():
|
|||||||
parser = config().option_parser('%prog '+ _('[options]\n\nStart the calibre content server.'))
|
parser = config().option_parser('%prog '+ _('[options]\n\nStart the calibre content server.'))
|
||||||
parser.add_option('--with-library', default=None,
|
parser.add_option('--with-library', default=None,
|
||||||
help=_('Path to the library folder to serve with the content server'))
|
help=_('Path to the library folder to serve with the content server'))
|
||||||
|
parser.add_option('--pidfile', default=None,
|
||||||
|
help=_('Write process PID to the specified file'))
|
||||||
|
parser.add_option('--daemonize', default=False, action='store_true',
|
||||||
|
help='Run process in background as a daemon. No effect on windows.')
|
||||||
return parser
|
return parser
|
||||||
|
|
||||||
|
def daemonize(stdin='/dev/null', stdout='/dev/null', stderr='/dev/null'):
|
||||||
|
try:
|
||||||
|
pid = os.fork()
|
||||||
|
if pid > 0:
|
||||||
|
# exit first parent
|
||||||
|
sys.exit(0)
|
||||||
|
except OSError, e:
|
||||||
|
print >>sys.stderr, "fork #1 failed: %d (%s)" % (e.errno, e.strerror)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# decouple from parent environment
|
||||||
|
os.chdir("/")
|
||||||
|
os.setsid()
|
||||||
|
os.umask(0)
|
||||||
|
|
||||||
|
# do second fork
|
||||||
|
try:
|
||||||
|
pid = os.fork()
|
||||||
|
if pid > 0:
|
||||||
|
# exit from second parent
|
||||||
|
sys.exit(0)
|
||||||
|
except OSError, e:
|
||||||
|
print >>sys.stderr, "fork #2 failed: %d (%s)" % (e.errno, e.strerror)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
# Redirect standard file descriptors.
|
||||||
|
si = file(stdin, 'r')
|
||||||
|
so = file(stdout, 'a+')
|
||||||
|
se = file(stderr, 'a+', 0)
|
||||||
|
os.dup2(si.fileno(), sys.stdin.fileno())
|
||||||
|
os.dup2(so.fileno(), sys.stdout.fileno())
|
||||||
|
os.dup2(se.fileno(), sys.stderr.fileno())
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def main(args=sys.argv):
|
def main(args=sys.argv):
|
||||||
parser = option_parser()
|
parser = option_parser()
|
||||||
opts, args = parser.parse_args(args)
|
opts, args = parser.parse_args(args)
|
||||||
|
if opts.daemonize and not iswindows:
|
||||||
|
daemonize()
|
||||||
|
if opts.pidfile is not None:
|
||||||
|
with open(opts.pidfile, 'wb') as f:
|
||||||
|
f.write(str(os.getpid()))
|
||||||
cherrypy.log.screen = True
|
cherrypy.log.screen = True
|
||||||
from calibre.utils.config import prefs
|
from calibre.utils.config import prefs
|
||||||
if opts.with_library is None:
|
if opts.with_library is None:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user