Esempio n. 1
0
def initialize(options):

    # HTTPS stuff stolen from sickbeard
    enable_https = options['enable_https']
    https_cert = options['https_cert']
    https_cert_chain = options['https_cert_chain']
    https_key = options['https_key']

    if enable_https:
        # If either the HTTPS certificate or key do not exist, try to make self-signed ones.
        if plexpy.CONFIG.HTTPS_CREATE_CERT and \
                (not (https_cert and os.path.exists(https_cert)) or
                 not (https_key and os.path.exists(https_key))):
            if not create_https_certificates(https_cert, https_key):
                logger.warn(
                    "Tautulli WebStart :: Unable to create certificate and key. Disabling HTTPS"
                )
                enable_https = False

        if not (os.path.exists(https_cert) and os.path.exists(https_key)):
            logger.warn(
                "Tautulli WebStart :: Disabled HTTPS because of missing certificate and key."
            )
            enable_https = False

    options_dict = {
        'server.socket_port': options['http_port'],
        'server.socket_host': options['http_host'],
        'environment': options['http_environment'],
        'server.thread_pool': 10,
        'server.max_request_body_size': 1073741824,
        'server.socket_timeout': 60,
        'tools.encode.on': True,
        'tools.encode.encoding': 'utf-8',
        'tools.decode.on': True
    }

    if plexpy.DEV:
        options_dict['environment'] = "test_suite"
        options_dict['engine.autoreload.on'] = True

    if enable_https:
        options_dict['server.ssl_certificate'] = https_cert
        options_dict['server.ssl_certificate_chain'] = https_cert_chain
        options_dict['server.ssl_private_key'] = https_key
        protocol = "https"
    else:
        protocol = "http"

    if options['http_proxy']:
        # Overwrite cherrypy.tools.proxy with our own proxy handler
        cherrypy.tools.proxy = cherrypy.Tool('before_handler',
                                             proxy,
                                             priority=1)

    if options['http_password']:
        login_allowed = [
            "Tautulli admin (username is '%s')" % options['http_username']
        ]
        if plexpy.CONFIG.HTTP_PLEX_ADMIN:
            login_allowed.append("Plex admin")

        logger.info(
            "Tautulli WebStart :: Web server authentication is enabled: %s.",
            ' and '.join(login_allowed))

        if options['http_basic_auth']:
            plexpy.AUTH_ENABLED = False
            basic_auth_enabled = True
        else:
            plexpy.AUTH_ENABLED = True
            basic_auth_enabled = False
            cherrypy.tools.auth = cherrypy.Tool('before_handler',
                                                webauth.check_auth,
                                                priority=2)
    else:
        plexpy.AUTH_ENABLED = False
        basic_auth_enabled = False

    if options['http_root'].strip('/'):
        plexpy.HTTP_ROOT = options['http_root'] = '/' + str(
            options['http_root'].strip('/')) + '/'
    else:
        plexpy.HTTP_ROOT = options['http_root'] = '/'

    cherrypy.config.update(options_dict)

    conf = {
        '/': {
            'engine.timeout_monitor.on':
            False,
            'tools.staticdir.root':
            os.path.join(plexpy.PROG_DIR, 'data'),
            'tools.proxy.on':
            bool(options['http_proxy']),
            'tools.gzip.on':
            True,
            'tools.gzip.mime_types': [
                'text/html', 'text/plain', 'text/css', 'text/javascript',
                'application/json', 'application/javascript'
            ],
            'tools.auth.on':
            plexpy.AUTH_ENABLED,
            'tools.auth_basic.on':
            basic_auth_enabled,
            'tools.auth_basic.realm':
            'Tautulli web server',
            'tools.auth_basic.checkpassword':
            cherrypy.lib.auth_basic.checkpassword_dict(
                {options['http_username']: options['http_password']})
        },
        '/api': {
            'tools.auth_basic.on': False
        },
        '/status': {
            'tools.auth_basic.on': False
        },
        '/interfaces': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': "interfaces",
            'tools.caching.on': True,
            'tools.caching.force': True,
            'tools.caching.delay': 0,
            'tools.expires.on': True,
            'tools.expires.secs': 60 * 60 * 24 * 30,  # 30 days
            'tools.sessions.on': False,
            'tools.auth.on': False
        },
        '/images': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': "interfaces/default/images",
            'tools.staticdir.content_types': {
                'svg': 'image/svg+xml'
            },
            'tools.caching.on': True,
            'tools.caching.force': True,
            'tools.caching.delay': 0,
            'tools.expires.on': True,
            'tools.expires.secs': 60 * 60 * 24 * 30,  # 30 days
            'tools.sessions.on': False,
            'tools.auth.on': False
        },
        '/css': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': "interfaces/default/css",
            'tools.caching.on': True,
            'tools.caching.force': True,
            'tools.caching.delay': 0,
            'tools.expires.on': True,
            'tools.expires.secs': 60 * 60 * 24 * 30,  # 30 days
            'tools.sessions.on': False,
            'tools.auth.on': False
        },
        '/fonts': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': "interfaces/default/fonts",
            'tools.caching.on': True,
            'tools.caching.force': True,
            'tools.caching.delay': 0,
            'tools.expires.on': True,
            'tools.expires.secs': 60 * 60 * 24 * 30,  # 30 days
            'tools.sessions.on': False,
            'tools.auth.on': False
        },
        '/js': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': "interfaces/default/js",
            'tools.caching.on': True,
            'tools.caching.force': True,
            'tools.caching.delay': 0,
            'tools.expires.on': True,
            'tools.expires.secs': 60 * 60 * 24 * 30,  # 30 days
            'tools.sessions.on': False,
            'tools.auth.on': False
        },
        '/cache': {
            'tools.staticdir.on': True,
            'tools.staticdir.dir': plexpy.CONFIG.CACHE_DIR,
            'tools.caching.on': True,
            'tools.caching.force': True,
            'tools.caching.delay': 0,
            'tools.expires.on': True,
            'tools.expires.secs': 60 * 60 * 24 * 30,  # 30 days
            'tools.sessions.on': False,
            'tools.auth.on': False
        },
        #'/pms_image_proxy': {
        #    'tools.staticdir.on': True,
        #    'tools.staticdir.dir': os.path.join(plexpy.CONFIG.CACHE_DIR, 'images'),
        #    'tools.caching.on': True,
        #    'tools.caching.force': True,
        #    'tools.caching.delay': 0,
        #    'tools.expires.on': True,
        #    'tools.expires.secs': 60 * 60 * 24 * 30,  # 30 days
        #    'tools.auth.on': False,
        #    'tools.sessions.on': False
        #},
        '/favicon.ico': {
            'tools.staticfile.on':
            True,
            'tools.staticfile.filename':
            os.path.abspath(
                os.path.join(
                    plexpy.PROG_DIR,
                    'data/interfaces/default/images/favicon/favicon.ico')),
            'tools.caching.on':
            True,
            'tools.caching.force':
            True,
            'tools.caching.delay':
            0,
            'tools.expires.on':
            True,
            'tools.expires.secs':
            60 * 60 * 24 * 30,  # 30 days
            'tools.sessions.on':
            False,
            'tools.auth.on':
            False
        }
    }

    cherrypy.tree.mount(WebInterface(), options['http_root'], config=conf)
    if plexpy.HTTP_ROOT != '/':
        cherrypy.tree.mount(BaseRedirect(), '/')

    try:
        logger.info(
            "Tautulli WebStart :: Starting Tautulli web server on %s://%s:%d%s",
            protocol, options['http_host'], options['http_port'],
            options['http_root'])
        #cherrypy.process.servers.check_port(str(options['http_host']), options['http_port'])
        if not plexpy.DEV:
            cherrypy.server.start()
        else:
            cherrypy.engine.signals.subscribe()
            cherrypy.engine.start()
            cherrypy.engine.block()
    except IOError as e:
        logger.error("Tautulli WebStart :: Failed to start Tautulli: %s", e)
        sys.exit(1)

    cherrypy.server.wait()
Esempio n. 2
0
def start():
    """ Main function for starting HTTP server """
    logger = logging.getLogger('htpc.server')
    logger.debug("Setting up to start cherrypy")
    protocol = ""

    # Set server ip, port and root
    cherrypy.config.update({
        'server.socket_host': htpc.HOST,
        'server.socket_port': htpc.PORT,
        'log.screen': False,
        'server.thread_pool': 15,
        'server.socket_queue_size': 10
    })

    # Wrap htpc manager in secure headers.
    # http://cherrypy.readthedocs.org/en/latest/advanced.html#securing-your-server
    if htpc.settings.get('app_use_secure_headers', True):
        cherrypy.tools.secureheaders = cherrypy.Tool('before_finalize',
                                                     secureheaders,
                                                     priority=60)
        cherrypy.config.update({'tools.secureheaders.on': True})

    # Enable auth if username and pass is set, add to db as admin
    if htpc.USERNAME and htpc.PASSWORD:
        """ Lets see if the that username and password is already in the db"""
        try:
            user = Manageusers.selectBy(username=htpc.USERNAME).getOne()
            # If the user exist
            if user:
                # Activate the new password
                user.password = htpc.PASSWORD

        except SQLObjectNotFound:
            logger.debug(
                "Added htpc.USERNAME and htpc.PASSWORD to Manageusers table")
            Manageusers(username=htpc.USERNAME,
                        password=htpc.PASSWORD,
                        role='admin')

        logger.debug('Updating cherrypy config, activating sessions and auth')

        cherrypy.config.update({
            'tools.sessions.on': True,
            'tools.auth.on': True,
            'tools.sessions.timeout': 43200,
            'tools.sessions.httponly': True
            #'tools.sessions.secure': True #  Auth does not work with this on #TODO
        })

    # Set server environment to production unless when debugging
    if not htpc.DEV:
        cherrypy.config.update({'environment': 'production'})

    if htpc.settings.get('app_use_ssl'):
        serverkey = os.path.join(htpc.DATADIR, 'server.key')
        cert = os.path.join(htpc.DATADIR, 'server.cert')
        # If either the HTTPS certificate or key do not exist, make some self-signed ones.
        if not (cert and os.path.exists(cert)) or not (
                serverkey and os.path.exists(serverkey)):
            logger.debug(
                'There isnt any certificate or key, trying to make them')
            if create_https_certificates(cert, serverkey):
                # Save the new crt and key to settings
                htpc.SSLKEY = htpc.settings.set('app_ssl_key', serverkey)
                htpc.SSLCERT = htpc.settings.set('app_ssl_cert', cert)
                htpc.ENABLESSL = True
                logger.debug("Created certificate and key successfully")
                logger.info("Restarting to activate SSL")
                do_restart()

        if (os.path.exists(htpc.settings.get('app_ssl_cert'))
                and os.path.exists(htpc.settings.get('app_ssl_key'))):
            htpc.ENABLESSL = True

    if htpc.ENABLESSL:
        protocol = "s"
        logger.debug("SSL is enabled")
        cherrypy.config.update({
            'server.ssl_certificate':
            htpc.settings.get('app_ssl_cert'),
            'server.ssl_private_key':
            htpc.settings.get('app_ssl_key')
        })

    if htpc.settings.get('app_use_proxy_headers'):
        cherrypy.config.update({'tools.proxy.on': True})

    if htpc.settings.get('app_use_proxy_headers') and htpc.settings.get(
            'app_use_proxy_headers_basepath'):
        cherrypy.config.update({
            'tools.proxy.base':
            str(htpc.settings.get('app_use_proxy_headers_basepath'))
        })

    # Daemonize cherrypy if specified
    if htpc.DAEMON:
        if sys.platform == 'win32':
            logger.error(
                "You are using Windows - I cannot setup daemon mode. Please use the pythonw executable instead."
            )
            logger.error(
                "More information at http://docs.python.org/2/using/windows.html."
            )
        else:
            Daemonizer(cherrypy.engine).subscribe()

    # Create PID if specified
    if htpc.PID:
        PIDFile(cherrypy.engine, htpc.PID).subscribe()

    def stopp_ap():
        htpc.SCHED.shutdown(wait=False)

    stopp_ap.priority = 10
    cherrypy.engine.subscribe('stop', stopp_ap)
    cherrypy.engine.timeout_monitor.unsubscribe()

    # Set static directories
    webdir = os.path.join(htpc.RUNDIR, htpc.TEMPLATE)
    favicon = os.path.join(webdir, "img/favicon.ico")
    app_config = {
        '/': {
            'tools.staticdir.root':
            webdir,
            'tools.encode.on':
            True,
            'tools.encode.encoding':
            'utf-8',
            'tools.gzip.on':
            True,
            'tools.gzip.mime_types': [
                'text/html', 'text/plain', 'text/css', 'text/javascript',
                'application/json', 'application/javascript'
            ]
        },
        '/js': {
            'tools.caching.on': True,
            'tools.caching.force': True,
            'tools.caching.delay': 0,
            'tools.expires.on': True,
            'tools.expires.secs': 60 * 60 * 24 * 30,
            'tools.staticdir.on': True,
            'tools.auth.on': False,
            'tools.sessions.on': False,
            'tools.staticdir.dir': 'js'
        },
        '/css': {
            'tools.caching.on': True,
            'tools.caching.force': True,
            'tools.caching.delay': 0,
            'tools.expires.on': True,
            'tools.expires.secs': 60 * 60 * 24 * 30,
            'tools.staticdir.on': True,
            'tools.auth.on': False,
            'tools.sessions.on': False,
            'tools.staticdir.dir': 'css'
        },
        '/img': {
            'tools.caching.on': True,
            'tools.caching.force': True,
            'tools.caching.delay': 0,
            'tools.expires.on': True,
            'tools.expires.secs': 60 * 60 * 24 * 30,
            'tools.staticdir.on': True,
            'tools.auth.on': False,
            'tools.sessions.on': False,
            'tools.staticdir.dir': 'img'
        },
        '/favicon.ico': {
            'tools.caching.on': True,
            'tools.caching.force': True,
            'tools.expires.on': True,
            'tools.expires.secs': 60 * 60 * 24 * 30,
            'tools.staticfile.on': True,
            'tools.auth.on': False,
            'tools.sessions.on': False,
            'tools.staticfile.filename': favicon
        }
    }

    # Start the CherryPy server
    logger.info("Starting up webserver")
    print '*******************************************************************'
    print 'Starting HTPC Manager on port ' + str(htpc.PORT) + '.'
    print 'Start your browser and go to http%s://localhost:%s%s' % (
        protocol, htpc.PORT, htpc.WEBDIR[:-1])
    print '*******************************************************************'
    cherrypy.quickstart(htpc.ROOT, htpc.WEBDIR[:-1], config=app_config)
Esempio n. 3
0
def start():
    """ Main function for starting HTTP server """
    logger = logging.getLogger('htpc.server')
    logger.debug("Setting up to start cherrypy")
    protocol = ""

    # Set server ip, port and root
    cherrypy.config.update({
        'server.socket_host': htpc.HOST,
        'server.socket_port': htpc.PORT,
        'log.screen': False,
        'server.thread_pool': 15,
        'server.socket_queue_size': 10
    })

    # Wrap htpc manager in secure headers.
    # http://cherrypy.readthedocs.org/en/latest/advanced.html#securing-your-server
    if htpc.settings.get('app_use_secure_headers', True):
        cherrypy.tools.secureheaders = cherrypy.Tool('before_finalize', secureheaders, priority=60)
        cherrypy.config.update({'tools.secureheaders.on': True})

    # Enable auth if username and pass is set, add to db as admin
    if htpc.USERNAME and htpc.PASSWORD:
        """ Lets see if the that username and password is already in the db"""
        try:
            user = Manageusers.selectBy(username=htpc.USERNAME).getOne()
            # If the user exist
            if user:
                # Activate the new password
                user.password = htpc.PASSWORD

        except SQLObjectNotFound:
            logger.debug("Added htpc.USERNAME and htpc.PASSWORD to Manageusers table")
            Manageusers(username=htpc.USERNAME, password=htpc.PASSWORD, role='admin')

        logger.debug('Updating cherrypy config, activating sessions and auth')

        cherrypy.config.update({
            'tools.sessions.on': True,
            'tools.auth.on': True,
            'tools.sessions.timeout': 43200,
            'tools.sessions.httponly': True
            #'tools.sessions.secure': True #  Auth does not work with this on #TODO
        })

    # Set server environment to production unless when debugging
    if not htpc.DEV:
        cherrypy.config.update({
            'environment': 'production'
        })

    if htpc.settings.get('app_use_ssl'):
        serverkey = os.path.join(htpc.DATADIR, 'server.key')
        cert = os.path.join(htpc.DATADIR, 'server.cert')
        # If either the HTTPS certificate or key do not exist, make some self-signed ones.
        if not (cert and os.path.exists(cert)) or not (serverkey and os.path.exists(serverkey)):
            logger.debug('There isnt any certificate or key, trying to make them')
            if create_https_certificates(cert, serverkey):
                # Save the new crt and key to settings
                htpc.SSLKEY = htpc.settings.set('app_ssl_key', serverkey)
                htpc.SSLCERT = htpc.settings.set('app_ssl_cert', cert)
                htpc.ENABLESSL = True
                logger.debug("Created certificate and key successfully")
                logger.info("Restarting to activate SSL")
                do_restart()

        if (os.path.exists(htpc.settings.get('app_ssl_cert')) and os.path.exists(htpc.settings.get('app_ssl_key'))):
            htpc.ENABLESSL = True

    if htpc.ENABLESSL:
        protocol = "s"
        logger.debug("SSL is enabled")
        cherrypy.config.update({
                'server.ssl_certificate': htpc.settings.get('app_ssl_cert'),
                'server.ssl_private_key': htpc.settings.get('app_ssl_key')

        })

    if htpc.settings.get('app_use_proxy_headers'):
        cherrypy.config.update({
                'tools.proxy.on': True

        })

    if htpc.settings.get('app_use_proxy_headers') and htpc.settings.get('app_use_proxy_headers_basepath'):
        cherrypy.config.update({
                'tools.proxy.base': str(htpc.settings.get('app_use_proxy_headers_basepath'))
        })

    # Daemonize cherrypy if specified
    if htpc.DAEMON:
        if sys.platform == 'win32':
            logger.error("You are using Windows - I cannot setup daemon mode. Please use the pythonw executable instead.")
            logger.error("More information at http://docs.python.org/2/using/windows.html.")
        else:
            Daemonizer(cherrypy.engine).subscribe()

    # Create PID if specified
    if htpc.PID:
        PIDFile(cherrypy.engine, htpc.PID).subscribe()

    def stopp_ap():
        htpc.SCHED.shutdown(wait=False)

    stopp_ap.priority = 10
    cherrypy.engine.subscribe('stop', stopp_ap)
    cherrypy.engine.timeout_monitor.unsubscribe()

    # Set static directories
    webdir = os.path.join(htpc.RUNDIR, htpc.TEMPLATE)
    favicon = os.path.join(webdir, "img/favicon.ico")
    app_config = {
        '/': {
            'tools.staticdir.root': webdir,
            'tools.encode.on': True,
            'tools.encode.encoding': 'utf-8',
            'tools.gzip.on': True,
            'tools.gzip.mime_types': ['text/html', 'text/plain', 'text/css', 'text/javascript', 'application/json', 'application/javascript']

        },
        '/js': {
            'tools.caching.on': True,
            'tools.caching.force': True,
            'tools.caching.delay': 0,
            'tools.expires.on': True,
            'tools.expires.secs': 60 * 60 * 24 * 30,
            'tools.staticdir.on': True,
            'tools.auth.on': False,
            'tools.sessions.on': False,
            'tools.staticdir.dir': 'js'
        },
        '/css': {
            'tools.caching.on': True,
            'tools.caching.force': True,
            'tools.caching.delay': 0,
            'tools.expires.on': True,
            'tools.expires.secs': 60 * 60 * 24 * 30,
            'tools.staticdir.on': True,
            'tools.auth.on': False,
            'tools.sessions.on': False,
            'tools.staticdir.dir': 'css'
        },
        '/img': {
            'tools.caching.on': True,
            'tools.caching.force': True,
            'tools.caching.delay': 0,
            'tools.expires.on': True,
            'tools.expires.secs': 60 * 60 * 24 * 30,
            'tools.staticdir.on': True,
            'tools.auth.on': False,
            'tools.sessions.on': False,
            'tools.staticdir.dir': 'img'
        },
        '/favicon.ico': {
            'tools.caching.on': True,
            'tools.caching.force': True,
            'tools.expires.on': True,
            'tools.expires.secs': 60 * 60 * 24 * 30,
            'tools.staticfile.on': True,
            'tools.auth.on': False,
            'tools.sessions.on': False,
            'tools.staticfile.filename': favicon
        }
    }

    # Start the CherryPy server
    logger.info("Starting up webserver")
    print '*******************************************************************'
    print 'Starting HTPC Manager on port ' + str(htpc.PORT) + '.'
    print 'Start your browser and go to http%s://localhost:%s%s' % (protocol, htpc.PORT, htpc.WEBDIR[:-1])
    print '*******************************************************************'
    cherrypy.quickstart(htpc.ROOT, htpc.WEBDIR[:-1], config=app_config)