home *** CD-ROM | disk | FTP | other *** search
/ Maximum CD 2011 January / maximum-cd-2011-01.iso / DiscContents / calibre-0.7.26.msi / file_1422 (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2010-10-31  |  8.9 KB  |  254 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. __license__ = 'GPL v3'
  5. __copyright__ = '2010, Kovid Goyal <kovid@kovidgoyal.net>'
  6. __docformat__ = 'restructuredtext en'
  7. import os
  8. import logging
  9. from logging.handlers import RotatingFileHandler
  10. import cherrypy
  11. from cherrypy.process.plugins import SimplePlugin
  12. from calibre.constants import __appname__, __version__
  13. from calibre.utils.date import fromtimestamp
  14. from calibre.library.server import listen_on, log_access_file, log_error_file
  15. from calibre.library.server.utils import expose
  16. from calibre.utils.mdns import publish as publish_zeroconf, stop_server as stop_zeroconf, get_external_ip
  17. from calibre.library.server.content import ContentServer
  18. from calibre.library.server.mobile import MobileServer
  19. from calibre.library.server.xml import XMLServer
  20. from calibre.library.server.opds import OPDSServer
  21. from calibre.library.server.cache import Cache
  22. from calibre.library.server.browse import BrowseServer
  23.  
  24. class DispatchController(object):
  25.     
  26.     def __init__(self, prefix, wsgi = False):
  27.         self.dispatcher = cherrypy.dispatch.RoutesDispatcher()
  28.         self.funcs = []
  29.         self.seen = set([])
  30.         self.prefix = None if prefix else ''
  31.         if wsgi:
  32.             self.prefix = ''
  33.         
  34.  
  35.     
  36.     def __call__(self, name, route, func, **kwargs):
  37.         if name in self.seen:
  38.             raise NameError('Route name: ' + repr(name) + ' already used')
  39.         name in self.seen
  40.         self.seen.add(name)
  41.         kwargs['action'] = 'f_%d' % len(self.funcs)
  42.         if route != '/':
  43.             route = self.prefix + route
  44.         
  45.         self.dispatcher.connect(name, route, self, **kwargs)
  46.         self.funcs.append(expose(func))
  47.  
  48.     
  49.     def __getattr__(self, attr):
  50.         if not attr.startswith('f_'):
  51.             raise AttributeError(attr + ' not found')
  52.         attr.startswith('f_')
  53.         num = attr.rpartition('_')[-1]
  54.         
  55.         try:
  56.             num = int(num)
  57.         except:
  58.             raise AttributeError(attr + ' not found')
  59.  
  60.         if num < 0 or num >= len(self.funcs):
  61.             raise AttributeError(attr + ' not found')
  62.         num >= len(self.funcs)
  63.         return self.funcs[num]
  64.  
  65.  
  66.  
  67. class BonJour(SimplePlugin):
  68.     
  69.     def __init__(self, engine, port = 8080, prefix = ''):
  70.         SimplePlugin.__init__(self, engine)
  71.         self.port = port
  72.         self.prefix = prefix
  73.  
  74.     
  75.     def start(self):
  76.         
  77.         try:
  78.             publish_zeroconf('Books in calibre', '_stanza._tcp', self.port, {
  79.                 'path': self.prefix + '/stanza' })
  80.         except:
  81.             import traceback
  82.             cherrypy.log.error('Failed to start BonJour:')
  83.             cherrypy.log.error(traceback.format_exc())
  84.  
  85.  
  86.     start.priority = 90
  87.     
  88.     def stop(self):
  89.         
  90.         try:
  91.             stop_zeroconf()
  92.         except:
  93.             import traceback
  94.             cherrypy.log.error('Failed to stop BonJour:')
  95.             cherrypy.log.error(traceback.format_exc())
  96.  
  97.  
  98.     stop.priority = 10
  99.  
  100. cherrypy.engine.bonjour = BonJour(cherrypy.engine)
  101.  
  102. class LibraryServer(ContentServer, MobileServer, XMLServer, OPDSServer, Cache, BrowseServer):
  103.     server_name = __appname__ + '/' + __version__
  104.     
  105.     def __init__(self, db, opts, embedded = False, show_tracebacks = True, wsgi = False):
  106.         self.is_wsgi = bool(wsgi)
  107.         self.opts = opts
  108.         self.embedded = embedded
  109.         self.state_callback = None
  110.         (self.max_cover_width, self.max_cover_height) = map(int, self.opts.max_cover.split('x'))
  111.         path = P('content_server')
  112.         self.build_time = fromtimestamp(os.stat(path).st_mtime)
  113.         self.default_cover = open(P('content_server/default_cover.jpg'), 'rb').read()
  114.         cherrypy.engine.bonjour.port = opts.port
  115.         cherrypy.engine.bonjour.prefix = opts.url_prefix
  116.         Cache.__init__(self)
  117.         self.set_database(db)
  118.         cherrypy.config.update({
  119.             'log.screen': opts.develop,
  120.             'engine.autoreload_on': getattr(opts, 'auto_reload', False),
  121.             'tools.log_headers.on': opts.develop,
  122.             'checker.on': opts.develop,
  123.             'request.show_tracebacks': show_tracebacks,
  124.             'server.socket_host': listen_on,
  125.             'server.socket_port': opts.port,
  126.             'server.socket_timeout': opts.timeout,
  127.             'server.thread_pool': opts.thread_pool })
  128.         if embedded or wsgi:
  129.             cherrypy.config.update({
  130.                 'engine.SIGHUP': None,
  131.                 'engine.SIGTERM': None })
  132.         
  133.         self.config = { }
  134.         self.is_running = False
  135.         self.exception = None
  136.         if not wsgi:
  137.             self.setup_loggers()
  138.             cherrypy.engine.bonjour.subscribe()
  139.             self.config['global'] = {
  140.                 'tools.gzip.on': True,
  141.                 'tools.gzip.mime_types': [
  142.                     'text/html',
  143.                     'text/plain',
  144.                     'text/xml',
  145.                     'text/javascript',
  146.                     'text/css'] }
  147.             if opts.password:
  148.                 self.config['/'] = {
  149.                     'tools.digest_auth.on': True,
  150.                     'tools.digest_auth.realm': _('Password to access your calibre library. Username is ') + opts.username.strip(),
  151.                     'tools.digest_auth.users': {
  152.                         opts.username.strip(): opts.password.strip() } }
  153.             
  154.         
  155.         self.__dispatcher__ = DispatchController(self.opts.url_prefix, wsgi)
  156.         for x in self.__class__.__bases__:
  157.             if hasattr(x, 'add_routes'):
  158.                 x.add_routes(self, self.__dispatcher__)
  159.                 continue
  160.         
  161.         root_conf = self.config.get('/', { })
  162.         root_conf['request.dispatch'] = self.__dispatcher__.dispatcher
  163.         self.config['/'] = root_conf
  164.  
  165.     
  166.     def set_database(self, db):
  167.         self.db = db
  168.         sr = getattr(self.opts, 'restriction', None)
  169.         sr = None if sr is None else sr
  170.         self.set_search_restriction(sr)
  171.  
  172.     
  173.     def graceful(self):
  174.         cherrypy.engine.graceful()
  175.  
  176.     
  177.     def set_search_restriction(self, restriction):
  178.         self.search_restriction_name = restriction
  179.         if restriction:
  180.             self.search_restriction = 'search:"%s"' % restriction
  181.         else:
  182.             self.search_restriction = ''
  183.         self.reset_caches()
  184.  
  185.     
  186.     def setup_loggers(self):
  187.         access_file = log_access_file
  188.         error_file = log_error_file
  189.         log = cherrypy.log
  190.         maxBytes = getattr(log, 'rot_maxBytes', 10000000)
  191.         backupCount = getattr(log, 'rot_backupCount', 1000)
  192.         h = RotatingFileHandler(error_file, 'a', maxBytes, backupCount)
  193.         h.setLevel(logging.DEBUG)
  194.         h.setFormatter(cherrypy._cplogging.logfmt)
  195.         log.error_log.addHandler(h)
  196.         h = RotatingFileHandler(access_file, 'a', maxBytes, backupCount)
  197.         h.setLevel(logging.DEBUG)
  198.         h.setFormatter(cherrypy._cplogging.logfmt)
  199.         log.access_log.addHandler(h)
  200.  
  201.     
  202.     def start(self):
  203.         self.is_running = False
  204.         cherrypy.tree.mount(root = None, config = self.config)
  205.         
  206.         try:
  207.             
  208.             try:
  209.                 cherrypy.engine.start()
  210.             except:
  211.                 ip = get_external_ip()
  212.                 if not ip or ip == '127.0.0.1':
  213.                     raise 
  214.                 ip == '127.0.0.1'
  215.                 cherrypy.log('Trying to bind to single interface: ' + ip)
  216.                 cherrypy.config.update({
  217.                     'server.socket_host': ip })
  218.                 cherrypy.engine.start()
  219.  
  220.             self.is_running = True
  221.             cherrypy.engine.block()
  222.         except Exception:
  223.             e = None
  224.             self.exception = e
  225.         finally:
  226.             self.is_running = False
  227.             
  228.             try:
  229.                 if callable(self.state_callback):
  230.                     self.state_callback(self.is_running)
  231.             except:
  232.                 pass
  233.  
  234.  
  235.  
  236.     
  237.     def exit(self):
  238.         
  239.         try:
  240.             cherrypy.engine.exit()
  241.         finally:
  242.             cherrypy.server.httpserver = None
  243.             self.is_running = False
  244.             
  245.             try:
  246.                 if callable(self.state_callback):
  247.                     self.state_callback(self.is_running)
  248.             except:
  249.                 pass
  250.  
  251.  
  252.  
  253.  
  254.