コード例 #1
0
ファイル: routing_test.py プロジェクト: yufi113/tornado
    def get_app(self):
        app = Application()

        def request_callable(request):
            request.connection.write_headers(
                ResponseStartLine("HTTP/1.1", 200, "OK"),
                HTTPHeaders({"Content-Length": "2"}))
            request.connection.write(b"OK")
            request.connection.finish()

        router = CustomRouter()
        router.add_routes({
            "/nested_handler": (app, _get_named_handler("nested_handler"))
        })

        app.add_handlers(".*", [
            (HostMatches("www.example.com"), [
                (PathMatches("/first_handler"),
                 "tornado.test.routing_test.SecondHandler", {}, "second_handler")
            ]),
            Rule(PathMatches("/.*handler"), router),
            Rule(PathMatches("/first_handler"), FirstHandler, name="first_handler"),
            Rule(PathMatches("/request_callable"), request_callable),
            ("/connection_delegate", ConnectionDelegate())
        ])

        return app
コード例 #2
0
    def make_web_app(self):
        # Start with web application routes
        app = Application([
            (r"/assets/(.*)", StaticFileHandler,
             dict(path=tornado_settings['static_path'])),
            (r"/dashboard/(.*)", MainUIRequestHandler,
             dict(
                 data_queues=self.data_queues,
                 foreman=self.foreman,
             )),
            (r"/dashws", DashboardWebSocket,
             dict(
                 data_queues=self.data_queues,
                 foreman=self.foreman,
             )),
            (r"/history/(.*)", HistoryUIRequestHandler,
             dict(data_queues=self.data_queues, )),
            (r"/plugins/(.*)", PluginsUIRequestHandler,
             dict(data_queues=self.data_queues, )),
            (r"/settings/(.*)", SettingsUIRequestHandler,
             dict(data_queues=self.data_queues, )),
            (r"/filebrowser/(.*)", ElementFileBrowserUIRequestHandler,
             dict(data_queues=self.data_queues, )),
            (r"/(.*)", RedirectHandler, dict(url="/dashboard/")),
        ], **tornado_settings)

        # Add API routes
        app.add_handlers(r'.*', [
            (PathMatches(r"/api/.*"), APIRequestRouter(app)),
        ])

        return app
コード例 #3
0
ファイル: webping.py プロジェクト: faketrue/pythonSample
def make_app(host, apipath):
    if host is None:
        return Application([(apipath, WebPing)])

    app = Application()
    app.add_handlers(host, [(apipath, WebPing)])
    return app
コード例 #4
0
    def __init__(self, app: Application,
                 pyctuator_impl: PyctuatorImpl) -> None:
        super().__init__(app, pyctuator_impl)

        custom_dumps = partial(json.dumps,
                               default=self._custom_json_serializer)

        app.settings.setdefault("pyctuator_router", self)
        app.settings.setdefault("custom_dumps", custom_dumps)

        # Register a log-function that records request and response in traces and than delegates to the original func
        self.delegate_log_function = app.settings.get("log_function")
        app.settings.setdefault("log_function",
                                self._intercept_request_and_response)

        app.add_handlers(".*$", [
            (r"/pyctuator", PyctuatorHandler),
            (r"/pyctuator/env", EnvHandler),
            (r"/pyctuator/info", InfoHandler),
            (r"/pyctuator/health", HealthHandler),
            (r"/pyctuator/metrics", MetricsHandler),
            (r"/pyctuator/metrics/(?P<metric_name>.*$)", MetricsNameHandler),
            (r"/pyctuator/loggers", LoggersHandler),
            (r"/pyctuator/loggers/(?P<logger_name>.*$)", LoggersNameHandler),
            (r"/pyctuator/dump", ThreadDumpHandler),
            (r"/pyctuator/threaddump", ThreadDumpHandler),
            (r"/pyctuator/logfile", LogFileHandler),
            (r"/pyctuator/trace", HttpTraceHandler),
            (r"/pyctuator/httptrace", HttpTraceHandler),
        ])
コード例 #5
0
ファイル: tornado.py プロジェクト: idom-team/idom
def _add_handler(app: Application, options: Options,
                 handlers: _RouteHandlerSpecs) -> None:
    prefixed_handlers: List[Any] = [
        (urljoin(options.url_prefix, route_pattern), ) + tuple(handler_info)
        for route_pattern, *handler_info in handlers
    ]
    app.add_handlers(r".*", prefixed_handlers)
コード例 #6
0
ファイル: routing_test.py プロジェクト: leeclemens/tornado
    def get_app(self):
        app = Application()

        def request_callable(request):
            request.connection.write_headers(
                ResponseStartLine("HTTP/1.1", 200, "OK"),
                HTTPHeaders({"Content-Length": "2"}))
            request.connection.write(b"OK")
            request.connection.finish()

        router = CustomRouter()
        router.add_routes({
            "/nested_handler": (app, _get_named_handler("nested_handler"))
        })

        app.add_handlers(".*", [
            (HostMatches("www.example.com"), [
                (PathMatches("/first_handler"),
                 "tornado.test.routing_test.SecondHandler", {}, "second_handler")
            ]),
            Rule(PathMatches("/.*handler"), router),
            Rule(PathMatches("/first_handler"), FirstHandler, name="first_handler"),
            Rule(PathMatches("/request_callable"), request_callable),
            ("/connection_delegate", ConnectionDelegate())
        ])

        return app
コード例 #7
0
ファイル: tornado.py プロジェクト: Beanstalk-Farms/idom
 def _setup_application(
     self,
     config: Config,
     app: Application,
 ) -> None:
     base_url = config["base_url"]
     app.add_handlers(
         r".*",
         [
             (urljoin(base_url, route_pattern), ) +
             tuple(handler_info)  # type: ignore
             for route_pattern, *handler_info in
             self._create_route_handlers(config)
         ],
     )
コード例 #8
0
ファイル: applet.py プロジェクト: gitbot/sentinel
    def __call__(self, application=None):
        """
        This is used to mount the handlers in the
        applet onto a new `tornado.web.Application` object or
        an existing one thats passed in.

        :arg tornado.web.Application application The application providing the
        mount point for the handlers in the applet. A new application object is
        created if this argument is `None`.
        """
        if not application:
            application = Application()

        application.add_handlers(self.host_pattern, self.handlers)
        return application
コード例 #9
0
def initWebServer(options={}):
    options.setdefault('port', 8081)
    options.setdefault('host', '0.0.0.0')
    options.setdefault('log_dir', None)
    options.setdefault('username', '')
    options.setdefault('password', '')
    options.setdefault('web_root', '/')
    assert isinstance(options['port'], int)
    assert 'data_root' in options

    # tornado setup

    # Load the app
    app = Application([],
                        debug=False,
                        gzip=True,
                        xheaders=sickbeard.HANDLE_REVERSE_PROXY,
                        cookie_secret='61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo='
    )

    # Main Handler
    app.add_handlers(".*$", [
        (r"%s" % options['web_root'], RedirectHandler, {'url': '%s/home/' % options['web_root']}),
        (r'%s/(.*)(/?)' % options['web_root'], webserve.MainHandler)
    ])

    # Static Path Handler
    app.add_handlers(".*$", [
        (r'%s/(favicon\.ico)' % options['web_root'], MultiStaticFileHandler,
         {'paths': [os.path.join(options['data_root'], 'images/ico/favicon.ico')]}),
        (r'%s/%s/(.*)(/?)' % (options['web_root'], 'images'), MultiStaticFileHandler,
         {'paths': [os.path.join(options['data_root'], 'images')]}),
        (r'%s/%s/(.*)(/?)' % (options['web_root'], 'css'), MultiStaticFileHandler,
         {'paths': [os.path.join(options['data_root'], 'css')]}),
        (r'%s/%s/(.*)(/?)' % (options['web_root'], 'js'), MultiStaticFileHandler,
         {'paths': [os.path.join(options['data_root'], 'js')]})

    ])

    global server

    protocol = "http"
    server = HTTPServer(app, no_keep_alive=True)

    logger.log(u"Starting SickRage on " + protocol + "://" + str(options['host']) + ":" + str(
        options['port']) + "/")

    server.listen(options['port'], options['host'])
コード例 #10
0
def application(
    route_list,
    Application,
    xsrf_cookies=False,
):
    app = Application(
        xsrf_cookies=xsrf_cookies,
        debug=app_config.DEBUG,
        gzip=True
    )

    for route in route_list:
        # print route.host, route.handlers
        app.add_handlers(route.host, route.handlers)

    return app
コード例 #11
0
    def get_app(self):
        app = Application()

        def request_callable(request):
            request.write(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK")
            request.finish()

        app.add_handlers(".*", [
            (HostMatches("www.example.com"), [
                (PathMatches("/first_handler"), "tornado.test.routing_test.SecondHandler", {}, "second_handler")
            ]),
            Rule(PathMatches("/first_handler"), FirstHandler, name="first_handler"),
            Rule(PathMatches("/request_callable"), request_callable),
            ("/connection_delegate", ConnectionDelegate())
        ])

        return app
コード例 #12
0
def application():
    """

    生成一个可用的应用程序,供http服务器调用

    :return: Application

    """
    settings = {
        "autoescape": "xhtml_escape",
        "websocket_ping_interval": None,

        # "static_path": "statics",
        # "static_url_prefix": "/static",
        "template_path": opt_template["template_path"],
        "cookie_secret": opt_secret["cookie_secret"],
        "xsrf_cookies": opt_secret["xsrf_cookies"] == "true",
        "ui_methods": ancient.uiMethod,
        "ui_modules": ancient.uiModule.registered_class,
        "debug": opt_debug["debug"] == "true",
        "autoreload": opt_debug["autoreload"] == "true",
        "compiled_template_cache":
        opt_debug["compiled_template_cache"] == "true",
        "static_hash_cache": opt_debug["static_hash_cache"] == "true",
        "serve_traceback": opt_debug["serve_traceback"] == "true",
    }
    domain_name = opt_server["domain"]
    if domain_name:
        app = Application(handlers=None, **settings)
        app.add_handlers(domain_name, routers())
        print("Local access : [ http://127.0.0.1:{} ]".format(options.port))
        print("Remote access : [ http://{0}:{1} ]".format(
            domain_name, options.port))
    else:
        app = Application(handlers=routers(), **settings)
        print("Local access : [ http://127.0.0.1:{} ]".format(options.port))
        network_index = int(opt_debug["network_index"])
        index = 0
        for ip in gethostbyname_ex(gethostname())[2]:
            index += 1
            url = "http://{}:{}".format(ip, options.port)
            print("Remote access : [ {} ]".format(url))
            if network_index == index:
                print_qrcode(url)
    return app
コード例 #13
0
ファイル: routing_test.py プロジェクト: zxyalp/tornado
    def get_app(self):
        app = Application()

        def request_callable(request):
            request.write(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK")
            request.finish()

        app.add_handlers(
            ".*", [(HostMatches("www.example.com"), [
                (PathMatches("/first_handler"),
                 "tornado.test.routing_test.SecondHandler", {},
                 "second_handler")
            ]),
                   Rule(PathMatches("/first_handler"),
                        FirstHandler,
                        name="first_handler"),
                   Rule(PathMatches("/request_callable"), request_callable),
                   ("/connection_delegate", ConnectionDelegate())])

        return app
コード例 #14
0
ファイル: flask_tornado.py プロジェクト: ryanss/flask-tornado
 def run(self, port=5000, host='127.0.0.1', **kwargs):
     if self.app.debug or kwargs.get('debug', False):
         # Attach debugger to Flask routes
         self.app.debug = True
         self.app.wsgi_app = DebuggedApplication(self.app.wsgi_app, True)
         # Attach debugger to Tornado routes
         self.debug_app = DebuggedApplication(WSGIAdapter(self), True)
         debug_container = WSGIContainer(self.debug_app)
         # Socket handlers must bypass debugger
         if hasattr(self, 'socket_handlers'):
             socket_app = Application([
                 (r".*", FallbackHandler, dict(fallback=WSGIContainer(self.debug_app)))
             ])
             socket_app.add_handlers(r".*", self.socket_handlers)
             http_server = HTTPServer(socket_app)
         else:
             http_server = HTTPServer(debug_container)
         autoreload.start()
     else:
         if hasattr(self, 'socket_handlers'):
             self.add_handlers(r".*", self.socket_handlers)
         http_server = HTTPServer(self)
     http_server.listen(port, address=host)
     IOLoop.current().start()
コード例 #15
0
ファイル: webserveInit.py プロジェクト: Arcanemagus/SickRage
class SRWebServer(threading.Thread):  # pylint: disable=too-many-instance-attributes
    def __init__(self, options=None, io_loop=None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.alive = True
        self.name = "TORNADO"
        self.io_loop = io_loop or IOLoop.current()

        self.options = options or {}
        self.options.setdefault("port", 8081)
        self.options.setdefault("host", "0.0.0.0")
        self.options.setdefault("log_dir", None)
        self.options.setdefault("username", "")
        self.options.setdefault("password", "")
        self.options.setdefault("web_root", "/")
        assert isinstance(self.options["port"], int)
        assert "data_root" in self.options

        self.server = None

        # video root
        if sickbeard.ROOT_DIRS:
            root_dirs = sickbeard.ROOT_DIRS.split("|")
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if self.options["web_root"]:
            sickbeard.WEB_ROOT = self.options["web_root"] = "/" + self.options["web_root"].lstrip("/").strip("/")

        # api root
        if not sickbeard.API_KEY:
            sickbeard.API_KEY = generateApiKey()
        self.options["api_root"] = r"{0}/api/{1}".format(sickbeard.WEB_ROOT, sickbeard.API_KEY)

        # tornado setup
        self.enable_https = self.options["enable_https"]
        self.https_cert = self.options["https_cert"]
        self.https_key = self.options["https_key"]

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert and ek(os.path.exists, self.https_cert)) or not (
                self.https_key and ek(os.path.exists, self.https_key)
            ):
                if not create_https_certificates(self.https_cert, self.https_key):
                    logger.log(u"Unable to create CERT/KEY files, disabling HTTPS")
                    sickbeard.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (ek(os.path.exists, self.https_cert) and ek(os.path.exists, self.https_key)):
                logger.log(u"Disabled HTTPS because of missing CERT and KEY files", logger.WARNING)
                sickbeard.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application(
            [],
            debug=True,
            autoreload=False,
            gzip=sickbeard.WEB_USE_GZIP,
            xheaders=sickbeard.HANDLE_REVERSE_PROXY,
            cookie_secret=sickbeard.WEB_COOKIE_SECRET,
            login_url="{0}/login/".format(self.options["web_root"]),
        )

        # Main Handlers
        self.app.add_handlers(
            ".*$",
            [
                # webapi handler
                (r"{0}(/?.*)".format(self.options["api_root"]), ApiHandler),
                # webapi key retrieval
                (r"{0}/getkey(/?.*)".format(self.options["web_root"]), KeyHandler),
                # webapi builder redirect
                (
                    r"{0}/api/builder".format(self.options["web_root"]),
                    RedirectHandler,
                    {"url": self.options["web_root"] + "/apibuilder/"},
                ),
                # webui login/logout handlers
                (r"{0}/login(/?)".format(self.options["web_root"]), LoginHandler),
                (r"{0}/logout(/?)".format(self.options["web_root"]), LogoutHandler),
                # Web calendar handler (Needed because option Unprotected calendar)
                (r"{0}/calendar".format(self.options["web_root"]), CalendarHandler),
                # webui handlers
            ]
            + route.get_routes(self.options["web_root"]),
        )

        # Static File Handlers
        self.app.add_handlers(
            ".*$",
            [
                # favicon
                (
                    r"{0}/(favicon\.ico)".format(self.options["web_root"]),
                    StaticFileHandler,
                    {"path": ek(os.path.join, self.options["data_root"], "images/ico/favicon.ico")},
                ),
                # images
                (
                    r"{0}/images/(.*)".format(self.options["web_root"]),
                    StaticFileHandler,
                    {"path": ek(os.path.join, self.options["data_root"], "images")},
                ),
                # cached images
                (
                    r"{0}/cache/images/(.*)".format(self.options["web_root"]),
                    StaticFileHandler,
                    {"path": ek(os.path.join, sickbeard.CACHE_DIR, "images")},
                ),
                # css
                (
                    r"{0}/css/(.*)".format(self.options["web_root"]),
                    StaticFileHandler,
                    {"path": ek(os.path.join, self.options["data_root"], "css")},
                ),
                # javascript
                (
                    r"{0}/js/(.*)".format(self.options["web_root"]),
                    StaticFileHandler,
                    {"path": ek(os.path.join, self.options["data_root"], "js")},
                ),
                # fonts
                (
                    r"{0}/fonts/(.*)".format(self.options["web_root"]),
                    StaticFileHandler,
                    {"path": ek(os.path.join, self.options["data_root"], "fonts")},
                ),
                # videos
                (r"{0}/videos/(.*)".format(self.options["web_root"]), StaticFileHandler, {"path": self.video_root}),
            ],
        )

    def run(self):
        if self.enable_https:
            protocol = "https"
            self.server = HTTPServer(self.app, ssl_options={"certfile": self.https_cert, "keyfile": self.https_key})
        else:
            protocol = "http"
            self.server = HTTPServer(self.app)

        logger.log(
            u"Starting SickRage on "
            + protocol
            + "://"
            + str(self.options["host"])
            + ":"
            + str(self.options["port"])
            + "/"
        )

        try:
            self.server.listen(self.options["port"], self.options["host"])
        except Exception:
            if sickbeard.LAUNCH_BROWSER and not self.daemon:
                sickbeard.launchBrowser(
                    "https" if sickbeard.ENABLE_HTTPS else "http", self.options["port"], sickbeard.WEB_ROOT
                )
                logger.log(u"Launching browser and exiting")
            logger.log(u"Could not start webserver on port {0}, already in use!".format(self.options["port"]))
            os._exit(1)  # pylint: disable=protected-access

        try:
            self.io_loop.start()
            self.io_loop.close(True)
        except (IOError, ValueError):
            # Ignore errors like "ValueError: I/O operation on closed kqueue fd". These might be thrown during a reload.
            pass

    def shutDown(self):
        self.alive = False
        self.io_loop.stop()
コード例 #16
0
ファイル: webserveInit.py プロジェクト: JackDandy/SickGear
class WebServer(threading.Thread):
    def __init__(self, options=None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.alive = True
        self.name = 'TORNADO'
        self.io_loop = None
        self.server = None

        self.options = options or {}
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', None)
        assert isinstance(self.options['port'], int)
        assert 'data_root' in self.options

        # web root
        self.options['web_root'] = ('/' + self.options['web_root'].lstrip('/')) if self.options['web_root'] else ''

        # tornado setup
        self.enable_https = self.options['enable_https']
        self.https_cert = self.options['https_cert']
        self.https_key = self.options['https_key']

        if self.enable_https:
            make_cert = False
            update_cfg = False
            for (attr, ext) in [('https_cert', '.crt'), ('https_key', '.key')]:
                ssl_path = getattr(self, attr, None)
                if ssl_path and not os.path.isfile(ssl_path):
                    if not ssl_path.endswith(ext):
                        setattr(self, attr, os.path.join(ssl_path, 'server%s' % ext))
                        setattr(sickbeard, attr.upper(), 'server%s' % ext)
                    make_cert = True

            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if make_cert:
                if not create_https_certificates(self.https_cert, self.https_key):
                    logger.log(u'Unable to create CERT/KEY files, disabling HTTPS')
                    update_cfg |= False is not sickbeard.ENABLE_HTTPS
                    sickbeard.ENABLE_HTTPS = False
                    self.enable_https = False
                else:
                    update_cfg = True

            if not (os.path.isfile(self.https_cert) and os.path.isfile(self.https_key)):
                logger.log(u'Disabled HTTPS because of missing CERT and KEY files', logger.WARNING)
                update_cfg |= False is not sickbeard.ENABLE_HTTPS
                sickbeard.ENABLE_HTTPS = False
                self.enable_https = False

            if update_cfg:
                sickbeard.save_config()

        # Load the app
        self.app = Application([],
                               debug=True,
                               serve_traceback=True,
                               autoreload=False,
                               compress_response=True,
                               cookie_secret=sickbeard.COOKIE_SECRET,
                               xsrf_cookies=True,
                               login_url='%s/login/' % self.options['web_root'])

        re_host_pattern = re_valid_hostname()

        # webui login/logout handlers
        self.app.add_handlers(re_host_pattern, [
            (r'%s/login(/?)' % self.options['web_root'], webserve.LoginHandler),
            (r'%s/logout(/?)' % self.options['web_root'], webserve.LogoutHandler),
        ])

        # Web calendar handler (Needed because option Unprotected calendar)
        self.app.add_handlers(re_host_pattern, [
            (r'%s/calendar' % self.options['web_root'], webserve.CalendarHandler),
        ])

        # Static File Handlers
        self.app.add_handlers(re_host_pattern, [
            # favicon
            (r'%s/(favicon\.ico)' % self.options['web_root'], webserve.BaseStaticFileHandler,
             {'path': os.path.join(self.options['data_root'], 'images/ico/favicon.ico')}),

            # images
            (r'%s/images/(.*)' % self.options['web_root'], webserve.BaseStaticFileHandler,
             {'path': os.path.join(self.options['data_root'], 'images')}),

            # cached images
            (r'%s/cache/images/(.*)' % self.options['web_root'], webserve.BaseStaticFileHandler,
             {'path': os.path.join(sickbeard.CACHE_DIR, 'images')}),

            # css
            (r'%s/css/(.*)' % self.options['web_root'], webserve.BaseStaticFileHandler,
             {'path': os.path.join(self.options['data_root'], 'css')}),

            # javascript
            (r'%s/js/(.*)' % self.options['web_root'], webserve.BaseStaticFileHandler,
             {'path': os.path.join(self.options['data_root'], 'js')}),

            (r'%s/kodi/(.*)' % self.options['web_root'], webserve.RepoHandler,
             {'path': os.path.join(sickbeard.CACHE_DIR, 'clients', 'kodi'),
              'default_filename': 'index.html'}),
        ])

        # Main Handler
        self.app.add_handlers(re_host_pattern, [
            (r'%s/api/builder(/?)(.*)' % self.options['web_root'], webserve.ApiBuilder),
            (r'%s/api(/?.*)' % self.options['web_root'], webapi.Api),
            (r'%s/imagecache(/?.*)' % self.options['web_root'], webserve.CachedImages),
            (r'%s/cache(/?.*)' % self.options['web_root'], webserve.Cache),
            (r'%s/config/general(/?.*)' % self.options['web_root'], webserve.ConfigGeneral),
            (r'%s/config/search(/?.*)' % self.options['web_root'], webserve.ConfigSearch),
            (r'%s/config/providers(/?.*)' % self.options['web_root'], webserve.ConfigProviders),
            (r'%s/config/subtitles(/?.*)' % self.options['web_root'], webserve.ConfigSubtitles),
            (r'%s/config/postProcessing(/?.*)' % self.options['web_root'], webserve.ConfigPostProcessing),
            (r'%s/config/notifications(/?.*)' % self.options['web_root'], webserve.ConfigNotifications),
            (r'%s/config/anime(/?.*)' % self.options['web_root'], webserve.ConfigAnime),
            (r'%s/config(/?.*)' % self.options['web_root'], webserve.Config),
            (r'%s/errorlogs(/?.*)' % self.options['web_root'], webserve.ErrorLogs),
            (r'%s/history(/?.*)' % self.options['web_root'], webserve.History),
            (r'%s/home/is_alive(/?.*)' % self.options['web_root'], webserve.IsAliveHandler),
            (r'%s/home/addShows(/?.*)' % self.options['web_root'], webserve.NewHomeAddShows),
            (r'%s/home/postprocess(/?.*)' % self.options['web_root'], webserve.HomePostProcess),
            (r'%s/home(/?.*)' % self.options['web_root'], webserve.Home),
            (r'%s/manage/manageSearches(/?.*)' % self.options['web_root'], webserve.ManageSearches),
            (r'%s/manage/showProcesses(/?.*)' % self.options['web_root'], webserve.showProcesses),
            (r'%s/manage/(/?.*)' % self.options['web_root'], webserve.Manage),
            (r'%s/ui(/?.*)' % self.options['web_root'], webserve.UI),
            (r'%s/browser(/?.*)' % self.options['web_root'], webserve.WebFileBrowser),
            (r'%s(/?update_watched_state_kodi/?)' % self.options['web_root'], webserve.NoXSRFHandler),
            (r'%s(/?.*)' % self.options['web_root'], webserve.MainHandler),
        ])

    def run(self):
        protocol, ssl_options = (('http', None),
                                 ('https', {'certfile': self.https_cert, 'keyfile': self.https_key}))[self.enable_https]

        logger.log(u'Starting SickGear on ' + protocol + '://' + str(self.options['host']) + ':' + str(
            self.options['port']) + '/')

        try:
            self.server = self.app.listen(self.options['port'], self.options['host'], ssl_options=ssl_options,
                                          xheaders=sickbeard.HANDLE_REVERSE_PROXY, protocol=protocol)
        except (StandardError, Exception):
            etype, evalue, etb = sys.exc_info()
            logger.log(
                'Could not start webserver on %s. Excpeption: %s, Error: %s' % (self.options['port'], etype, evalue),
                logger.ERROR)
            return

        self.io_loop = IOLoop.current()

        try:
            self.io_loop.start()
            self.io_loop.close(True)
        except (IOError, ValueError):
            # Ignore errors like 'ValueError: I/O operation on closed kqueue fd'. These might be thrown during a reload.
            pass

    def shut_down(self):
        self.alive = False
        if None is not self.io_loop:
            self.io_loop.stop()
コード例 #17
0
class PupyWebServer(object):
    def __init__(self, pupsrv, config):
        self.pupsrv = pupsrv
        self.config = config
        self.clients = {}
        self.mappings = {}

        self.ssl = False

        self.wwwroot = self.config.get(
            'webserver', 'static_webroot_uri', None) or \
            self.random_path()

        self.preserve_payloads = self.config.getboolean(
            'webserver', 'preserve_payloads')

        self.root = self.config.get_folder('wwwroot')

        self.app = None

        self._thread = None
        self._ioloop = None

        self.listen = config.get('webserver', 'listen')
        if ':' in self.listen:
            hostname, port = self.listen.rsplit(':', 1)
            port = int(port)
            self.hostname, self.port = hostname, port
        else:
            self.hostname = self.listen
            self.port = 9000

        self.served_files = set()
        self.aliases = {}
        self.show_requests = self.config.getboolean('webserver', 'log')

    def log(self, handler):
        if not self.show_requests:
            return

        message = 'Web: '

        if handler.request.uri in self.aliases:
            message += '({}) '.format(self.aliases[handler.request.uri])

        message += handler._request_summary()

        if handler.get_status() < 400:
            self.pupsrv.info(Success(message))
        else:
            self.pupsrv.info(Error(message))

    def start(self):
        webstatic = self.config.get_folder('webstatic', create=False)
        cert = self.config.get('webserver', 'cert', None)
        key = self.config.get('webserver', 'key', None)

        self.app = TornadoApplication([
            (r'/', IndexHandler),
            (self.wwwroot + '/(.*)', PayloadsHandler, {
                'path': self.root,
                'mappings': self.mappings,
            }),
            (r'/static/(.*)', TornadoStaticFileHandler, {
                'path': webstatic
            }),
        ],
                                      debug=False,
                                      template_path=webstatic,
                                      log_function=self.log,
                                      default_handler_class=ErrorHandler,
                                      default_handler_args={
                                          'status_code': 404,
                                      })

        ssl_options = None

        if key and cert:
            ssl_options = create_default_context(certfile=cert,
                                                 keyfile=key,
                                                 server_side=True)
            self.ssl = True

        self.app.listen(self.port,
                        address=self.hostname,
                        ssl_options=ssl_options)

        self._ioloop = tornado.ioloop.IOLoop.instance()

        self._thread = threading.Thread(target=self._ioloop.start)
        self._thread.daemon = True
        self._thread.start()

        self._registered = {}

    def stop(self):
        self._ioloop.stop()
        self._ioloop = None
        self._thread = None

        for (_, _, cleanup) in self._registered.itervalues():
            if cleanup:
                cleanup()

        self.mappings = {}
        self.aliases = {}

        if self.preserve_payloads:
            return

        for filepath in self.served_files:
            if path.isfile(filepath):
                unlink(filepath)

    def get_random_path_at_webroot(self):
        while True:
            filename = ''.join(random.choice(
                string.ascii_uppercase + \
                string.ascii_lowercase + \
                string.digits) for _ in range(10))

            filepath = path.join(self.root, filename)
            if not path.isfile(filepath):
                return filepath, filename

    def random_path(self):
        return '/'+''.join(
            random.choice(
                string.ascii_uppercase + \
                string.ascii_lowercase + \
                string.digits) for _ in range(10))

    def register_mapping(self, name):
        name = self.random_path()
        self.mappings[name] = path
        if name in self.mappings:
            del self.mappings[name]

    def is_registered(self, name):
        return self._registered.get(name, (None, None, None))[0]

    def serve_content(self, content, alias=None, as_file=True):
        uri = None

        if as_file:
            filepath, filename = self.get_random_path_at_webroot()
            try:
                with open(filepath, 'w') as out:
                    out.write(content)
                self.served_files.add(filepath)
            except:
                if path.isfile(filepath):
                    path.unlink(filepath)

                raise

            uri = self.wwwroot + '/' + filename
        else:
            uri = self.random_path()
            self.app.add_handlers('.*', [(uri, StaticTextHandler, {
                'content': content
            })])

        if alias:
            self.aliases[uri] = alias

        return uri

    def start_webplugin(self, name, web_handlers, cleanup=None):
        random_path = self.random_path()

        if name in self._registered:
            random_path, _, _ = self._registered[name]
            return self.port, random_path

        klasses = []

        for tab in web_handlers:
            if len(tab) == 2:
                uri_path, handler = tab
                kwargs = {}
            else:
                uri_path, handler, kwargs = tab

            ends_with_slash = uri_path.endswith('/')
            uri_path = '/'.join(x for x in [random_path] + uri_path.split('/')
                                if x)
            if ends_with_slash:
                uri_path += '/'

            klasses.append(handler)

            if issubclass(handler,
                          (ErrorHandler, WebSocketHandler, RequestHandler,
                           StaticTextHandler, PayloadsHandler, IndexHandler)):

                kwargs['config'] = self.config

            self.app.add_handlers(".*", [(uri_path, handler, kwargs)])
            self.pupsrv.info('Register webhook for {} at {}'.format(
                name, uri_path))

        self._registered[name] = random_path, klasses, cleanup

        return self.port, random_path

    def stop_webplugin(self, name):

        if name not in self._registered:
            return

        self.pupsrv.info('Unregister webhook for {}'.format(name))

        random_path, klasses, cleanup = self._registered[name]
        removed = False

        to_remove = []
        for rule in self.app.wildcard_router.rules:
            if rule.target in klasses:
                to_remove.append(rule)
                removed = True
            elif rule.matcher.regex.pattern.startswith(random_path):
                to_remove.append(rule)
                removed = True

        for rule in to_remove:
            self.app.wildcard_router.rules.remove(rule)

        to_remove = []
        for rule in self.app.default_router.rules:
            if rule.target in klasses:
                to_remove.append(rule)
                removed = True
            elif rule.matcher.regex.pattern.startswith(random_path):
                to_remove.append(rule)
                removed = True

        if cleanup:
            cleanup()

        if removed:
            del self._registered[name]
        else:
            self.pupsrv.info('{} was not found [error]'.format(name))
コード例 #18
0
def runCouchPotato(options,
                   base_path,
                   args,
                   data_dir=None,
                   log_dir=None,
                   Env=None,
                   desktop=None):

    try:
        locale.setlocale(locale.LC_ALL, "")
        encoding = locale.getpreferredencoding()
    except (locale.Error, IOError):
        encoding = None

    # for OSes that are poorly configured I'll just force UTF-8
    if not encoding or encoding in ('ANSI_X3.4-1968', 'US-ASCII', 'ASCII'):
        encoding = 'UTF-8'

    Env.set('encoding', encoding)

    # Do db stuff
    db_path = sp(os.path.join(data_dir, 'database'))
    old_db_path = os.path.join(data_dir, 'couchpotato.db')

    # Remove database folder if both exists
    if os.path.isdir(db_path) and os.path.isfile(old_db_path):
        db = SuperThreadSafeDatabase(db_path)
        db.open()
        db.destroy()

    # Check if database exists
    db = SuperThreadSafeDatabase(db_path)
    db_exists = db.exists()
    if db_exists:

        # Backup before start and cleanup old backups
        backup_path = sp(os.path.join(data_dir, 'db_backup'))
        backup_count = 5
        existing_backups = []
        if not os.path.isdir(backup_path): os.makedirs(backup_path)

        for root, dirs, files in os.walk(backup_path):
            # Only consider files being a direct child of the backup_path
            if root == backup_path:
                for backup_file in sorted(files):
                    ints = re.findall('\d+', backup_file)

                    # Delete non zip files
                    if len(ints) != 1:
                        os.remove(os.path.join(root, backup_file))
                    else:
                        existing_backups.append((int(ints[0]), backup_file))
            else:
                # Delete stray directories.
                shutil.rmtree(root)

        # Remove all but the last 5
        for eb in existing_backups[:-backup_count]:
            os.remove(os.path.join(backup_path, eb[1]))

        # Create new backup
        new_backup = sp(
            os.path.join(backup_path, '%s.tar.gz' % int(time.time())))
        zipf = tarfile.open(new_backup, 'w:gz')
        for root, dirs, files in os.walk(db_path):
            for zfilename in files:
                zipf.add(os.path.join(root, zfilename),
                         arcname='database/%s' %
                         os.path.join(root[len(db_path) + 1:], zfilename))
        zipf.close()

        # Open last
        db.open()

    else:
        db.create()

    # Force creation of cachedir
    log_dir = sp(log_dir)
    cache_dir = sp(os.path.join(data_dir, 'cache'))
    python_cache = sp(os.path.join(cache_dir, 'python'))

    if not os.path.exists(cache_dir):
        os.mkdir(cache_dir)
    if not os.path.exists(python_cache):
        os.mkdir(python_cache)

    # Register environment settings
    Env.set('app_dir', sp(base_path))
    Env.set('data_dir', sp(data_dir))
    Env.set('log_path', sp(os.path.join(log_dir, 'CouchPotato.log')))
    Env.set('db', db)
    Env.set('http_opener', requests.Session())
    Env.set('cache_dir', cache_dir)
    Env.set('cache', FileSystemCache(python_cache))
    Env.set('console_log', options.console_log)
    Env.set('quiet', options.quiet)
    Env.set('desktop', desktop)
    Env.set('daemonized', options.daemon)
    Env.set('args', args)
    Env.set('options', options)

    # Determine debug
    debug = options.debug or Env.setting('debug', default=False, type='bool')
    Env.set('debug', debug)

    # Development
    development = Env.setting('development', default=False, type='bool')
    Env.set('dev', development)

    # Disable logging for some modules
    for logger_name in [
            'enzyme', 'guessit', 'subliminal', 'apscheduler', 'tornado',
            'requests'
    ]:
        logging.getLogger(logger_name).setLevel(logging.ERROR)

    for logger_name in ['gntp']:
        logging.getLogger(logger_name).setLevel(logging.WARNING)

    # Disable SSL warning
    disable_warnings()

    # Use reloader
    reloader = debug is True and development and not Env.get(
        'desktop') and not options.daemon

    # Logger
    logger = logging.getLogger()
    formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s',
                                  '%m-%d %H:%M:%S')
    level = logging.DEBUG if debug else logging.INFO
    logger.setLevel(level)
    logging.addLevelName(19, 'INFO')

    # To screen
    if (debug or
            options.console_log) and not options.quiet and not options.daemon:
        hdlr = logging.StreamHandler(sys.stderr)
        hdlr.setFormatter(formatter)
        logger.addHandler(hdlr)

    # To file
    hdlr2 = handlers.RotatingFileHandler(Env.get('log_path'),
                                         'a',
                                         500000,
                                         10,
                                         encoding=Env.get('encoding'))
    hdlr2.setFormatter(formatter)
    logger.addHandler(hdlr2)

    # Start logging & enable colors
    # noinspection PyUnresolvedReferences
    import color_logs
    from couchpotato.core.logger import CPLog
    log = CPLog(__name__)
    log.debug('Started with options %s', options)

    # Check available space
    try:
        total_space, available_space = getFreeSpace(data_dir)
        if available_space < 100:
            log.error(
                'Shutting down as CP needs some space to work. You\'ll get corrupted data otherwise. Only %sMB left',
                available_space)
            return
    except:
        log.error('Failed getting diskspace: %s', traceback.format_exc())

    def customwarn(message, category, filename, lineno, file=None, line=None):
        log.warning('%s %s %s line:%s', (category, message, filename, lineno))

    warnings.showwarning = customwarn

    # Create app
    from couchpotato import WebHandler
    web_base = ('/' + Env.setting('url_base').lstrip('/') +
                '/') if Env.setting('url_base') else '/'
    Env.set('web_base', web_base)

    api_key = Env.setting('api_key')
    if not api_key:
        api_key = uuid4().hex
        Env.setting('api_key', value=api_key)

    api_base = r'%sapi/%s/' % (web_base, api_key)
    Env.set('api_base', api_base)

    # Basic config
    host = Env.setting('host', default='0.0.0.0')
    # app.debug = development
    config = {
        'use_reloader': reloader,
        'port': tryInt(Env.setting('port', default=5050)),
        'host': host if host and len(host) > 0 else '0.0.0.0',
        'ssl_cert': Env.setting('ssl_cert', default=None),
        'ssl_key': Env.setting('ssl_key', default=None),
    }

    # Load the app
    application = Application(
        [],
        log_function=lambda x: None,
        debug=config['use_reloader'],
        gzip=True,
        cookie_secret=api_key,
        login_url='%slogin/' % web_base,
    )
    Env.set('app', application)

    # Request handlers
    application.add_handlers(
        ".*$",
        [
            (r'%snonblock/(.*)(/?)' % api_base, NonBlockHandler),

            # API handlers
            (r'%s(.*)(/?)' % api_base, ApiHandler),  # Main API handler
            (r'%sgetkey(/?)' % web_base, KeyHandler),  # Get API key
            (r'%s' % api_base, RedirectHandler, {
                "url": web_base + 'docs/'
            }),  # API docs

            # Login handlers
            (r'%slogin(/?)' % web_base, LoginHandler),
            (r'%slogout(/?)' % web_base, LogoutHandler),

            # Catch all webhandlers
            (r'%s(.*)(/?)' % web_base, WebHandler),
            (r'(.*)', WebHandler),
        ])

    # Static paths
    static_path = '%sstatic/' % web_base
    for dir_name in ['fonts', 'images', 'scripts', 'style']:
        application.add_handlers(
            ".*$",
            [('%s%s/(.*)' % (static_path, dir_name), StaticFileHandler, {
                'path':
                sp(os.path.join(base_path, 'couchpotato', 'static', dir_name))
            })])
    Env.set('static_path', static_path)

    # Load configs & plugins
    loader = Env.get('loader')
    loader.preload(root=sp(base_path))
    loader.run()

    # Fill database with needed stuff
    fireEvent('database.setup')
    if not db_exists:
        fireEvent('app.initialize', in_order=True)
    fireEvent('app.migrate')

    # Go go go!
    from tornado.ioloop import IOLoop
    from tornado.autoreload import add_reload_hook
    loop = IOLoop.current()

    # Reload hook
    def reload_hook():
        fireEvent('app.shutdown')

    add_reload_hook(reload_hook)

    # Some logging and fire load event
    try:
        log.info('Starting server on port %(port)s', config)
    except:
        pass
    fireEventAsync('app.load')

    ssl_options = None
    if config['ssl_cert'] and config['ssl_key']:
        ssl_options = {
            'certfile': config['ssl_cert'],
            'keyfile': config['ssl_key'],
        }

    server = HTTPServer(application,
                        no_keep_alive=True,
                        ssl_options=ssl_options)

    try_restart = True
    restart_tries = 5

    while try_restart:
        try:
            server.listen(config['port'], config['host'])
            loop.start()
            server.close_all_connections()
            server.stop()
            loop.close(all_fds=True)
        except Exception as e:
            log.error('Failed starting: %s', traceback.format_exc())
            try:
                nr, msg = e
                if nr == 48:
                    log.info(
                        'Port (%s) needed for CouchPotato is already in use, try %s more time after few seconds',
                        (config.get('port'), restart_tries))
                    time.sleep(1)
                    restart_tries -= 1

                    if restart_tries > 0:
                        continue
                    else:
                        return
            except ValueError:
                return
            except:
                pass

            raise

        try_restart = False
コード例 #19
0
ファイル: httpd.py プロジェクト: pombredanne/compactor
class HTTPD(object):  # noqa
  """
  HTTP Server implementation that attaches to an event loop and socket, and
  is capable of handling mesos wire protocol messages.
  """

  def __init__(self, sock, loop):
    """
    Construct an HTTP server on a socket given an ioloop.
    """

    self.loop = loop
    self.sock = sock

    self.app = Application(handlers=[(r'/.*$', Blackhole)])
    self.server = HTTPServer(self.app, io_loop=self.loop)
    self.server.add_sockets([sock])

    self.sock.listen(1024)

  def terminate(self):
    log.info('Terminating HTTP server and all connections')

    self.server.close_all_connections()
    self.sock.close()

  def mount_process(self, process):
    """
    Mount a Process onto the http server to receive message callbacks.
    """

    for route_path in process.route_paths:
      route = '/%s%s' % (process.pid.id, route_path)
      log.info('Mounting route %s' % route)
      self.app.add_handlers('.*$', [(
          re.escape(route),
          RoutedRequestHandler,
          dict(process=process, path=route_path)
      )])

    for message_name in process.message_names:
      route = '/%s/%s' % (process.pid.id, message_name)
      log.info('Mounting message handler %s' % route)
      self.app.add_handlers('.*$', [(
          re.escape(route),
          WireProtocolMessageHandler,
          dict(process=process, name=message_name)
      )])

  def unmount_process(self, process):
    """
    Unmount a process from the http server to stop receiving message
    callbacks.
    """

    # There is no remove_handlers, but .handlers is public so why not.  server.handlers is a list of
    # 2-tuples of the form (host_pattern, [list of RequestHandler]) objects.  We filter out all
    # handlers matching our process from the RequestHandler list for each host pattern.
    def nonmatching(handler):
      return 'process' not in handler.kwargs or handler.kwargs['process'] != process

    def filter_handlers(handlers):
      host_pattern, handlers = handlers
      return (host_pattern, list(filter(nonmatching, handlers)))

    self.app.handlers = [filter_handlers(handlers) for handlers in self.app.handlers]
コード例 #20
0
class SRWebServer(threading.Thread):
    def __init__(self, options={}, io_loop=None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.alive = True
        self.name = "TORNADO"
        self.io_loop = io_loop or IOLoop.current()

        self.options = options
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', '/')
        assert isinstance(self.options['port'], int)
        assert 'data_root' in self.options

        # video root
        if sickbeard.ROOT_DIRS:
            root_dirs = sickbeard.ROOT_DIRS.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if self.options['web_root']:
            sickbeard.WEB_ROOT = self.options['web_root'] = ('/' + self.options['web_root'].lstrip('/').strip('/'))

        # api root
        if not sickbeard.API_KEY:
            sickbeard.API_KEY = generateApiKey()
        self.options['api_root'] = r'%s/api/%s' % (sickbeard.WEB_ROOT, sickbeard.API_KEY)

        # tornado setup
        self.enable_https = self.options['enable_https']
        self.https_cert = self.options['https_cert']
        self.https_key = self.options['https_key']

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert and os.path.exists(self.https_cert)) or not (
                        self.https_key and os.path.exists(self.https_key)):
                if not create_https_certificates(self.https_cert, self.https_key):
                    logger.log(u"Unable to create CERT/KEY files, disabling HTTPS")
                    sickbeard.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (os.path.exists(self.https_cert) and os.path.exists(self.https_key)):
                logger.log(u"Disabled HTTPS because of missing CERT and KEY files", logger.WARNING)
                sickbeard.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application([],
                                 debug=True,
                                 autoreload=False,
                                 gzip=True,
                                 xheaders=sickbeard.HANDLE_REVERSE_PROXY,
                                 cookie_secret='61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=',
                                 login_url='/login/',
        )

        # Main Handlers
        self.app.add_handlers('.*$', [
            # webapi handler
            (r'%s(/?.*)' % self.options['api_root'], ApiHandler),

            # webapi key retrieval
            (r'%s/getkey(/?.*)' % self.options['web_root'], KeyHandler),

            # webapi builder redirect
            (r'%s/api/builder' % self.options['web_root'], RedirectHandler, {"url": self.options['web_root'] + '/apibuilder/'}),

            # webui login/logout handlers
            (r'%s/login(/?.*)' % self.options['web_root'], LoginHandler),
            (r'%s/logout(/?.*)' % self.options['web_root'], LogoutHandler),

            # webui redirect
            (r'/', RedirectHandler, {"url": self.options['web_root'] + '/home/'}),

            # webui handlers
        ] + route.get_routes(self.options['web_root']))

        # Static File Handlers
        self.app.add_handlers(".*$", [
            # favicon
            (r'%s/(favicon\.ico)' % self.options['web_root'], StaticFileHandler,
             {"path": os.path.join(self.options['data_root'], 'images/ico/favicon.ico')}),

            # images
            (r'%s/images/(.*)' % self.options['web_root'], StaticFileHandler,
             {"path": os.path.join(self.options['data_root'], 'images')}),

            # cached images
            (r'%s/cache/images/(.*)' % self.options['web_root'], StaticFileHandler,
             {"path": os.path.join(sickbeard.CACHE_DIR, 'images')}),

            # css
            (r'%s/css/(.*)' % self.options['web_root'], StaticFileHandler,
             {"path": os.path.join(self.options['data_root'], 'css')}),

            # javascript
            (r'%s/js/(.*)' % self.options['web_root'], StaticFileHandler,
             {"path": os.path.join(self.options['data_root'], 'js')}),

            # videos
        ] + [(r'%s/videos/(.*)' % self.options['web_root'], StaticFileHandler,
              {"path": self.video_root})])

    def run(self):
        if self.enable_https:
            protocol = "https"
            self.server = HTTPServer(self.app, ssl_options={"certfile": self.https_cert, "keyfile": self.https_key})
        else:
            protocol = "http"
            self.server = HTTPServer(self.app)

        logger.log(u"Starting SickRage on " + protocol + "://" + str(self.options['host']) + ":" + str(
            self.options['port']) + "/")

        try:
            self.server.listen(self.options['port'], self.options['host'])
        except:
            etype, evalue, etb = sys.exc_info()
            logger.log(
                "Could not start webserver on %s. Excpeption: %s, Error: %s" % (self.options['port'], etype, evalue),
                logger.ERROR)
            return

        try:
            self.io_loop.start()
            self.io_loop.close(True)
        except (IOError, ValueError):
            # Ignore errors like "ValueError: I/O operation on closed kqueue fd". These might be thrown during a reload.
            pass

    def shutDown(self):
        self.alive = False
        self.io_loop.stop()
コード例 #21
0
ファイル: webserveInit.py プロジェクト: dnssyste/SickRage
def initWebServer(options={}):
    options.setdefault('port', 8081)
    options.setdefault('host', '0.0.0.0')
    options.setdefault('log_dir', None)
    options.setdefault('username', '')
    options.setdefault('password', '')
    options.setdefault('web_root', '/')
    assert isinstance(options['port'], int)
    assert 'data_root' in options

    def http_error_401_hander(status, message, traceback, version):
        """ Custom handler for 401 error """
        if status != "401 Unauthorized":
            logger.log(u"Tornado caught an error: %s %s" % (status, message), logger.ERROR)
            logger.log(traceback, logger.DEBUG)
        return r'''<!DOCTYPE html>
<html>
    <head>
        <title>%s</title>
    </head>
    <body>
        <br/>
        <font color="#0000FF">Error %s: You need to provide a valid username and password.</font>
    </body>
</html>
''' % ('Access denied', status)

    def http_error_404_hander(status, message, traceback, version):
        """ Custom handler for 404 error, redirect back to main page """
        return r'''<!DOCTYPE html>
<html>
    <head>
        <title>404</title>
        <script type="text/javascript" charset="utf-8">
          <!--
          location.href = "%s/home/"
          //-->
        </script>
    </head>
    <body>
        <br/>
    </body>
</html>
''' % options['web_root']

    # tornado setup
    enable_https = options['enable_https']
    https_cert = options['https_cert']
    https_key = options['https_key']

    if enable_https:
        # If either the HTTPS certificate or key do not exist, make some self-signed ones.
        if 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.log(u"Unable to create CERT/KEY files, disabling HTTPS")
                sickbeard.ENABLE_HTTPS = False
                enable_https = False

        if not (os.path.exists(https_cert) and os.path.exists(https_key)):
            logger.log(u"Disabled HTTPS because of missing CERT and KEY files", logger.WARNING)
            sickbeard.ENABLE_HTTPS = False
            enable_https = False

    # Load the app
    app = Application([],
                        debug=True,
                        gzip=True,
                        autoreload=True,
                        xheaders=False,
                        cookie_secret='61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=',
                        login_url='/login'
    )

    # Index Handler
    app.add_handlers(".*$", [
        (r"/", RedirectHandler, {'url': '/home/'}),
        (r'/login', webserve.LoginHandler),
        (r'/api/(.*)(/?)', webapi.Api),
        (r'%s(.*)(/?)' % options['web_root'], webserve.IndexHandler)
    ])

    # Static Path Handler
    app.add_handlers(".*$", [
        ('%s/%s/(.*)([^/]*)' % (options['web_root'], 'images'), MultiStaticFileHandler,
         {'paths': [os.path.join(options['data_root'], 'images'),
                    os.path.join(sickbeard.CACHE_DIR, 'images'),
                    os.path.join(sickbeard.CACHE_DIR, 'images', 'thumbnails')]}),
        ('%s/%s/(.*)([^/]*)' % (options['web_root'], 'css'), MultiStaticFileHandler,
         {'paths': [os.path.join(options['data_root'], 'css')]}),
        ('%s/%s/(.*)([^/]*)' % (options['web_root'], 'js'), MultiStaticFileHandler,
         {'paths': [os.path.join(options['data_root'], 'js')]})

    ])

    global server

    if enable_https:
        protocol = "https"
        server = HTTPServer(app, no_keep_alive=True,
                                 ssl_options={"certfile": https_cert, "keyfile": https_key})
    else:
        protocol = "http"
        server = HTTPServer(app, no_keep_alive=True)

    logger.log(u"Starting SickRage on " + protocol + "://" + str(options['host']) + ":" + str(
        options['port']) + "/")

    server.listen(options['port'], options['host'])
コード例 #22
0
ファイル: webserveInit.py プロジェクト: coderbone/SickRage
class SRWebServer(threading.Thread):
    def __init__(self, options={}, io_loop=None):
        threading.Thread.__init__(self)
        self.name = "TORNADO"
        self.alive = True

        self.io_loop = io_loop or IOLoop.current()

        self.options = options
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', '/')
        assert isinstance(self.options[b'port'], int)
        assert 'gui_root' in self.options

        # video root
        if sickbeard.ROOT_DIRS:
            root_dirs = sickbeard.ROOT_DIRS.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if self.options[b'web_root']:
            sickbeard.WEB_ROOT = self.options[b'web_root'] = ('/' + self.options[b'web_root'].lstrip('/').strip('/'))

        # api root
        if not sickbeard.API_KEY:
            sickbeard.API_KEY = generateApiKey()
        self.options[b'api_root'] = r'%s/api/%s' % (sickbeard.WEB_ROOT, sickbeard.API_KEY)

        # tornado setup
        self.enable_https = self.options[b'enable_https']
        self.https_cert = self.options[b'https_cert']
        self.https_key = self.options[b'https_key']

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert and ek(os.path.exists, self.https_cert)) or not (
                        self.https_key and ek(os.path.exists, self.https_key)):
                if not create_https_certificates(self.https_cert, self.https_key):
                    logging.info("Unable to create CERT/KEY files, disabling HTTPS")
                    sickbeard.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (os.path.exists(self.https_cert) and ek(os.path.exists, self.https_key)):
                logging.warning("Disabled HTTPS because of missing CERT and KEY files")
                sickbeard.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application([],
                               debug=sickbeard.DEBUG,
                               autoreload=False,
                               gzip=sickbeard.WEB_USE_GZIP,
                               xheaders=sickbeard.HANDLE_REVERSE_PROXY,
                               cookie_secret=sickbeard.WEB_COOKIE_SECRET,
                               login_url='%s/login/' % self.options[b'web_root'],
                               )

        # Main Handlers
        self.app.add_handlers('.*$', [
            # webapi handler
            (r'%s(/?.*)' % self.options[b'api_root'], ApiHandler),

            # webapi key retrieval
            (r'%s/getkey(/?.*)' % self.options[b'web_root'], KeyHandler),

            # webapi builder redirect
            (r'%s/api/builder' % self.options[b'web_root'], RedirectHandler,
             {"url": self.options[b'web_root'] + '/apibuilder/'}),

            # webui login/logout handlers
            (r'%s/login(/?)' % self.options[b'web_root'], LoginHandler),
            (r'%s/logout(/?)' % self.options[b'web_root'], LogoutHandler),

            # webui handlers
        ] + route.get_routes(self.options[b'web_root']))

        # Web calendar handler (Needed because option Unprotected calendar)
        self.app.add_handlers('.*$', [
            (r'%s/calendar' % self.options[b'web_root'], CalendarHandler),
        ])

        # Static File Handlers
        self.app.add_handlers(".*$", [
            # favicon
            (r'%s/(favicon\.ico)' % self.options[b'web_root'], StaticFileHandler,
             {"path": ek(os.path.join, self.options[b'gui_root'], 'images/ico/favicon.ico')}),

            # images
            (r'%s.*?/images/(.*)' % self.options[b'web_root'], StaticImageHandler,
             {"path": ek(os.path.join, self.options[b'gui_root'], 'images')}),

            # css
            (r'%s/css/(.*)' % self.options[b'web_root'], StaticFileHandler,
             {"path": ek(os.path.join, self.options[b'gui_root'], 'css')}),

            # javascript
            (r'%s/js/(.*)' % self.options[b'web_root'], StaticFileHandler,
             {"path": ek(os.path.join, self.options[b'gui_root'], 'js')}),

            # videos
        ] + [(r'%s/videos/(.*)' % self.options[b'web_root'], StaticFileHandler,
              {"path": self.video_root})])

    def run(self):
        protocol = 'http'
        self.server = HTTPServer(self.app)

        if self.enable_https:
            protocol = 'https'
            self.server.ssl_options={"certfile": self.https_cert, "keyfile": self.https_key}

        logging.info("Starting SiCKRAGE web server on [{}://{}:{}/]".format(protocol, self.options[b'host'],
                                                                           self.options[b'port']))

        try:
            self.server.listen(self.options[b'port'], self.options[b'host'])
        except:
            logging.info("Could not start webserver on port %s, already in use!" % self.options[b'port'])
            os._exit(1)

        if sickbeard.LAUNCH_BROWSER and not sickbeard.DAEMONIZE:
            self.io_loop.add_callback(sickbeard.launchBrowser, protocol, sickbeard.WEB_PORT, sickbeard.WEB_ROOT)

        try:
            self.io_loop.start()
            self.io_loop.close(True)
        except (IOError, ValueError):
            pass

    def shutDown(self):
        self.alive = False
        self.io_loop.stop()
コード例 #23
0
ファイル: __init__.py プロジェクト: TATUMTOT/SickRage
class SRWebServer(object):
    def __init__(self, **kwargs):
        self.running = True
        self.restart = False
        self.io_loop = IOLoop.instance()

        self.options = {}
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', '/')
        self.options.setdefault('stop_timeout', 3)
        self.options.update(kwargs)

        # video root
        if sickrage.ROOT_DIRS:
            root_dirs = sickrage.ROOT_DIRS.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if self.options[b'web_root']:
            sickrage.WEB_ROOT = self.options[b'web_root'] = ('/' + self.options[b'web_root'].lstrip('/').strip('/'))

        # api root
        if not sickrage.API_KEY:
            sickrage.API_KEY = generateApiKey()
        self.options[b'api_root'] = r'%s/api/%s' % (sickrage.WEB_ROOT, sickrage.API_KEY)

        # tornado setup
        self.enable_https = self.options[b'enable_https']
        self.https_cert = self.options[b'https_cert']
        self.https_key = self.options[b'https_key']

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert and os.path.exists(self.https_cert)) or not (
                        self.https_key and os.path.exists(self.https_key)):
                if not create_https_certificates(self.https_cert, self.https_key):
                    sickrage.LOGGER.info("Unable to create CERT/KEY files, disabling HTTPS")
                    sickrage.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (os.path.exists(self.https_cert) and os.path.exists(self.https_key)):
                sickrage.LOGGER.warning("Disabled HTTPS because of missing CERT and KEY files")
                sickrage.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application([],
                               debug=sickrage.DEBUG,
                               autoreload=False,
                               gzip=sickrage.WEB_USE_GZIP,
                               xheaders=sickrage.HANDLE_REVERSE_PROXY,
                               cookie_secret=sickrage.WEB_COOKIE_SECRET,
                               login_url='%s/login/' % self.options[b'web_root'],
                               )

        # Main Handlers
        self.app.add_handlers('.*$', [
            # webapi handler
            (r'%s(/?.*)' % self.options[b'api_root'], ApiHandler),

            # webapi key retrieval
            (r'%s/getkey(/?.*)' % self.options[b'web_root'], KeyHandler),

            # webapi builder redirect
            (r'%s/api/builder' % self.options[b'web_root'], RedirectHandler,
             {"url": self.options[b'web_root'] + '/apibuilder/'}),

            # webui login/logout handlers
            (r'%s/login(/?)' % self.options[b'web_root'], LoginHandler),
            (r'%s/logout(/?)' % self.options[b'web_root'], LogoutHandler),

            # webui handlers
        ] + route.get_routes(self.options[b'web_root']))

        # Web calendar handler (Needed because option Unprotected calendar)
        self.app.add_handlers('.*$', [
            (r'%s/calendar' % self.options[b'web_root'], CalendarHandler),
        ])

        # Static File Handlers
        self.app.add_handlers(".*$", [
            # favicon
            (r'%s/(favicon\.ico)' % self.options[b'web_root'], StaticFileHandler,
             {"path": os.path.join(self.options[b'gui_root'], 'images/ico/favicon.ico')}),

            # images
            (r'%s.*?/images/(.*)' % self.options[b'web_root'], StaticImageHandler,
             {"path": os.path.join(self.options[b'gui_root'], 'images')}),

            # css
            (r'%s/css/(.*)' % self.options[b'web_root'], StaticFileHandler,
             {"path": os.path.join(self.options[b'gui_root'], 'css')}),

            # javascript
            (r'%s/js/(.*)' % self.options[b'web_root'], StaticFileHandler,
             {"path": os.path.join(self.options[b'gui_root'], 'js')}),

            # videos
        ] + [(r'%s/videos/(.*)' % self.options[b'web_root'], StaticFileHandler,
              {"path": self.video_root})])

        # daemonize sickrage
        if sickrage.DAEMONIZE:
            import daemon
            ctx = daemon.DaemonContext()
            ctx.initgroups = False
            ctx.open()

        # write sickrage pidfile
        sickrage.PID = os.getpid()
        if sickrage.CREATEPID:
            with file(sickrage.PIDFILE, 'w+') as pf:
                pf.write(str(sickrage.PID))

        self.io_loop.add_callback(sickrage.Scheduler.start)

    def start(self):
        threading.currentThread().setName("TORNADO")

        try:
            self.server = HTTPServer(self.app)
            if self.enable_https:
                self.server.ssl_options = {"certfile": self.https_cert, "keyfile": self.https_key}
            self.server.listen(self.options[b'port'], self.options[b'host'])

            # start tornado web server
            from sickrage.core.helpers import get_lan_ip
            sickrage.LOGGER.info("Starting SiCKRAGE web server on [{}://{}:{}/]".format(
                            ('http', 'https')[sickrage.ENABLE_HTTPS], get_lan_ip(), sickrage.WEB_PORT))

            # launch browser window
            if sickrage.LAUNCH_BROWSER and not any([sickrage.WEB_NOLAUNCH, sickrage.DAEMONIZE]):
                sickrage.LOGGER.info("Launching browser window")
                threading.Thread(None, lambda: launch_browser(('http', 'https')[sickrage.ENABLE_HTTPS], sickrage.WEB_PORT, sickrage.WEB_ROOT)).start()

            sickrage.STARTED = True
            self.io_loop.start()
        except (KeyboardInterrupt, SystemExit) as e:
            sickrage.LOGGER.info('PERFORMING SHUTDOWN')
        except Exception as e:
            sickrage.LOGGER.info("TORNADO failed to start: {}".format(e))
        finally:
            self.server_shutdown()
            sickrage.LOGGER.shutdown()


    @staticmethod
    def remove_pid_file():
        try:
            if os.path.exists(sickrage.PIDFILE):
                os.remove(sickrage.PIDFILE)
        except (IOError, OSError):
            pass

    def server_restart(self):
        sickrage.LOGGER.info('PERFORMING RESTART')
        import tornado.autoreload
        tornado.autoreload.add_reload_hook(self.server_shutdown)
        tornado.autoreload.start()
        tornado.autoreload._reload()

    def server_shutdown(self):
        self.server.stop()
        if self.running:
            self.io_loop.stop()

        # shutdown sickrage
        if sickrage.STARTED:
            sickrage.core.halt()
            sickrage.core.saveall()

        if sickrage.DAEMONIZE and sickrage.PIDFILE:
            self.remove_pid_file()

        sickrage.LOGGER.info('SHUTDOWN/RESTART COMPLETED!')
コード例 #24
0
ファイル: __init__.py プロジェクト: Oseriduun/SiCKRAGE
class srWebServer(object):
    def __init__(self):
        self.io_loop = IOLoop.instance()
        self.running = True
        self.restart = False
        self.open_browser = False

        self.port = sickrage.srConfig.WEB_PORT
        self.host = sickrage.srConfig.WEB_HOST

        # video root
        if sickrage.srConfig.ROOT_DIRS:
            root_dirs = sickrage.srConfig.ROOT_DIRS.split("|")
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if sickrage.srConfig.WEB_ROOT:
            sickrage.srConfig.WEB_ROOT = sickrage.srConfig.WEB_ROOT = "/" + sickrage.srConfig.WEB_ROOT.lstrip(
                "/"
            ).strip("/")

        # api root
        if not sickrage.srConfig.API_KEY:
            sickrage.srConfig.API_KEY = generateApiKey()
        self.api_root = r"%s/api/%s" % (sickrage.srConfig.WEB_ROOT, sickrage.srConfig.API_KEY)

        # tornado setup
        if sickrage.srConfig.ENABLE_HTTPS:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (sickrage.srConfig.HTTPS_CERT and os.path.exists(sickrage.srConfig.HTTPS_CERT)) or not (
                sickrage.srConfig.HTTPS_KEY and os.path.exists(sickrage.srConfig.HTTPS_KEY)
            ):
                if not create_https_certificates(sickrage.srConfig.HTTPS_CERT, sickrage.srConfig.HTTPS_KEY):
                    sickrage.srLogger.info("Unable to create CERT/KEY files, disabling HTTPS")
                    sickrage.srConfig.ENABLE_HTTPS = False

            if not (os.path.exists(sickrage.srConfig.HTTPS_CERT) and os.path.exists(sickrage.srConfig.HTTPS_KEY)):
                sickrage.srLogger.warning("Disabled HTTPS because of missing CERT and KEY files")
                sickrage.srConfig.ENABLE_HTTPS = False

        # Load the app
        self.app = Application(
            [],
            debug=sickrage.srConfig.DEBUG,
            autoreload=False,
            gzip=sickrage.srConfig.WEB_USE_GZIP,
            xheaders=sickrage.srConfig.HANDLE_REVERSE_PROXY,
            cookie_secret=sickrage.srConfig.WEB_COOKIE_SECRET,
            login_url="%s/login/" % sickrage.srConfig.WEB_ROOT,
        )

        # Main Handlers
        self.app.add_handlers(
            ".*$",
            [
                # webapi handler
                (r"%s(/?.*)" % self.api_root, ApiHandler),
                # webapi key retrieval
                (r"%s/getkey(/?.*)" % sickrage.srConfig.WEB_ROOT, KeyHandler),
                # webapi builder redirect
                (
                    r"%s/api/builder" % sickrage.srConfig.WEB_ROOT,
                    RedirectHandler,
                    {"url": sickrage.srConfig.WEB_ROOT + "/apibuilder/"},
                ),
                # webui login/logout handlers
                (r"%s/login(/?)" % sickrage.srConfig.WEB_ROOT, LoginHandler),
                (r"%s/logout(/?)" % sickrage.srConfig.WEB_ROOT, LogoutHandler),
                # webui handlers
            ]
            + Route.get_routes(sickrage.srConfig.WEB_ROOT),
        )

        # Web calendar handler (Needed because option Unprotected calendar)
        self.app.add_handlers(".*$", [(r"%s/calendar" % sickrage.srConfig.WEB_ROOT, CalendarHandler)])

        # Static File Handlers
        self.app.add_handlers(
            ".*$",
            [
                # favicon
                (
                    r"%s/(favicon\.ico)" % sickrage.srConfig.WEB_ROOT,
                    StaticFileHandler,
                    {"path": os.path.join(sickrage.srConfig.GUI_DIR, "images/ico/favicon.ico")},
                ),
                # images
                (
                    r"%s.*?/images/(.*)" % sickrage.srConfig.WEB_ROOT,
                    StaticImageHandler,
                    {"path": os.path.join(sickrage.srConfig.GUI_DIR, "images")},
                ),
                # css
                (
                    r"%s/css/(.*)" % sickrage.srConfig.WEB_ROOT,
                    StaticFileHandler,
                    {"path": os.path.join(sickrage.srConfig.GUI_DIR, "css")},
                ),
                # javascript
                (
                    r"%s/js/(.*)" % sickrage.srConfig.WEB_ROOT,
                    StaticFileHandler,
                    {"path": os.path.join(sickrage.srConfig.GUI_DIR, "js")},
                ),
                # videos
            ]
            + [(r"%s/videos/(.*)" % sickrage.srConfig.WEB_ROOT, StaticFileHandler, {"path": self.video_root})],
        )

    def start(self):
        threading.currentThread().setName("TORNADO")

        try:
            self.server = HTTPServer(self.app)
            if sickrage.srConfig.ENABLE_HTTPS:
                self.server.ssl_options = {
                    "certfile": sickrage.srConfig.HTTPS_CERT,
                    "keyfile": sickrage.srConfig.HTTPS_KEY,
                }
            self.server.listen(self.port, self.host)

            # launch browser window
            if self.open_browser:
                threading.Thread(
                    None,
                    lambda: launch_browser(
                        ("http", "https")[sickrage.srConfig.ENABLE_HTTPS],
                        sickrage.srConfig.WEB_PORT,
                        sickrage.srConfig.WEB_ROOT,
                    ),
                ).start()

            sickrage.srConfig.STARTED = True

            sickrage.srLogger.info(
                "SiCKRAGE STARTED :: VERSION:[{}] CONFIG:[{}] URL:[{}://{}:{}/]".format(
                    sickrage.srCore.VERSION,
                    sickrage.srConfig.CONFIG_FILE,
                    ("http", "https")[sickrage.srConfig.ENABLE_HTTPS],
                    get_lan_ip(),
                    sickrage.srConfig.WEB_PORT,
                )
            )

            self.io_loop.start()
        except (KeyboardInterrupt, SystemExit) as e:
            sickrage.srLogger.info("PERFORMING SHUTDOWN")
        except Exception as e:
            sickrage.srLogger.info("TORNADO failed to start: {}".format(e.message))
        finally:
            self.server_shutdown()
            sickrage.srLogger.shutdown()

    def server_restart(self):
        sickrage.srLogger.info("PERFORMING RESTART")
        import tornado.autoreload

        tornado.autoreload.add_reload_hook(self.server_shutdown)
        tornado.autoreload.start()
        tornado.autoreload._reload()

    def server_shutdown(self):
        self.server.stop()
        if self.running:
            self.io_loop.stop()

        # shutdown sickrage
        if sickrage.srCore.STARTED:
            sickrage.srCore.halt()
            sickrage.srCore.save_all()

        sickrage.srLogger.info("SHUTDOWN COMPLETED!")
コード例 #25
0
ファイル: app.py プロジェクト: ismetacar/flasky-tornado
class FlaskyApp(object):
    """The Bant object provides a convenient API to configure
    :class:`~tornado.web.Application` It acts as a container for all
    plugins, crosscutting concern functions, objects and settings.
    On invocation of run method, Bant instance registers
    :class:`~flasky.handler.DynamicHandler` classes for every endpoint that
    is defined by user.

    Bant instance might be created at the :file:`__init__.py` of your package.
    Another approach might be creating initialization closures to init
    API functions. For more information please refer to :ref: ::

        from bant import Bant
        app = Bant(**settings)


    :param ioloop: IOLoop that will be used by application. By default
                   Bant application uses :class:`asyncio.BaseEventLoop`

    :param settings: Application specific settings.

    """

    #: The class for used as object container
    #: See :class:`~flasky.DIContainer`
    #: TODO: This fill be deleted
    di_class = DIContainer

    #: The class for used as parameter resolver
    #: See :class: `~flasky.parameters.ParameterResolver`
    #: TODO: This will be deleted
    parameter_resolver_class = ParameterResolver

    #: The class for used as cache manager
    #: See :class: `~flasky.cache.CacheManager`
    #: TODO: This will be deleted
    cache_manager_class = CacheManager

    #: Default plugins which will be loaded at the initialization of FlaskyApp.
    #: Users might manipulate the value of this list and prevent the loading of
    #: module
    default_plugins = ["di", "parameters", "caches"]

    #: The name of the logger to use.
    logger_name = "flasky.logger"

    def __init__(self, ioloop=None, **settings):

        #: :class:`tornado.ioloop.IOLoop` which will be used to run
        #: application. Default ioloop class is
        #: :class:`tornado.asyncio.AsyncIOMainLoop`
        self.ioloop = ioloop or self._get_ioloop()

        #: Please look :meth:`~build_app`
        self.is_builded = False

        #: The debug flag. This flag will be passed to tornado.Application
        #: If the debug flag set True, Application will be reload on every
        #: if code changes detected and Application will spit detailed
        #: logging information.
        self.debug = False

        #: Configuration dictionary, there might be better implementation for
        #: this in future versions
        self.settings = settings

        #: :class:`tornado.web.Application` instance for this flaskyApp.
        #: This instance will be injected to :class:`handler.DynamicHandler`
        #: TODO: change this variable name to tornado_app
        self.app = None

        #: List of functions which will be runned before any request
        #: will be handled. This functions might be used
        #: for any initialization routine
        self.on_start_funcs = []

        #: A list of functions which will be called at the beginning of the
        #: request. Before request functions can be used to perform common
        #: cross-cutting concerns (logging, authorization etc.)
        #: To register a function use the :meth:`before_request` decorator
        self.before_request_funcs = []

        #: A list of functions which will be called after the request handled
        #: by handler function. Function should take 2 parameters, a
        #: :class:`~tornado.web.RequestHandler` instance and endpoint
        #: definition.
        #:
        #: **Warning**: These functions will not be called if any error occurs
        #: during the execution of handler. To run piece of code after request
        #: in every circumstances please please check :meth:`teardown_request`
        #:
        #: To register a function use the :meth:`after_request` decorator
        self.after_request_funcs = []

        #: A list of functions which will be called after request is handled
        #: this function will be called even if any error exists on handler
        #: function. This method can :meth:`on_teardown_request`
        self.teardown_request_funcs = []

        #: A error specific handler registry. Key will be
        #: type of error and None type will be used as
        #: default error handler.
        #:
        #: To register an error handler, use the :meth:`error_handler`
        #: decorator
        self.error_handlers = {None: default_error_handler_func}

        #: Registered handler definitions
        #: All handlers registered under a tree which path might be accessed
        #: like this::
        #:
        #:      handler_function =
        #:          self.host_definitions['0.0.0.0']['/api/token']['POST']
        #:
        self.host_definitions = OrderedDict()

        #: Registered static file handlers, on build time this definitions
        #: will be converted to :class:`tornado.web.StaticFileHandler`. You
        #: can serve static file like this::
        #:
        #:      from flasky.app import FlaskyApp
        #:
        #:      app = FlaskyApp()
        #:      app.serve_static_file("/static/([^/]+)", "path/to/static/file")
        #:
        self.static_file_handler_definitions = []

        #: Executor which will be injected to handlers, max_worker_count of
        #: settings might be used to manage size of ThreadPoolExecutor.
        #: Default value is 1
        self.executor = ThreadPoolExecutor(
            max_workers=(settings.get('max_worker_count', None) or 1))

        #: Built-in plugins
        #: TODO: Implement plugin mechanisms
        self.di = self.di_class(self)
        self.parameter_resolver = self.parameter_resolver_class(self)
        self.cache = self.cache_manager_class(self)
        self.scheduler = Scheduler(self.ioloop)

    def _get_ioloop(self):
        from tornado.platform.asyncio import AsyncIOMainLoop
        if not hasattr(IOLoop, "_instance"):
            AsyncIOMainLoop().install()
        return IOLoop.current()

    def api(self, host='.*$', endpoint=None, method=None, **kwargs):
        """A decorator which will be used to register a handler for given
        endpoint. Parameters are default :class:`tornado.web.RequestHandler`
        parameters. Regexes can be used at endpoint definition and will be
        injected to as second parameter::

            @app.api(
                endpoint="/api/user",
                method="POST"
            )
            async def create_user(handler, *args, **kwargs):
                handler.write("hello world")

            @app.api(
                endpoint="api/user",
                method="GET"
            )
            async def get_users(handler, *args, **kwargs):
                handler.write({"user": "******"})

        :param host: Host Address in which this handler function will be
                     registered.

        :param endpoint: Endpoint address for which this handler function
                         will be executed.

        :param method: HTTP Method(POST, GET, PUT etc..) for which
                       this handler function will be executed

        :param options:" Options that will be attached to handler function
                        all the way throught middleware pipeline
        """
        host_definition = self.host_definitions.get(host, None)
        if host_definition is None:
            host_definition = OrderedDict()
            self.host_definitions[host] = host_definition

        endpoint_definition = self.host_definitions[host].get(endpoint, None)
        if endpoint_definition is None:
            endpoint_definition = OrderedDict()
            for supported_method in DynamicHandler.SUPPORTED_METHODS:
                endpoint_definition[supported_method] = OrderedDict()
            host_definition[endpoint] = endpoint_definition

        def decorator(f):
            if not iscoroutinefunction(f):
                raise ConfigurationError(
                    message="Function [{}] should be"
                    "coroutine in order to use.".format(f.__name__))

            if not endpoint:
                raise ConfigurationError(
                    message='Endpoint should be provided.')

            if not method:
                raise ConfigurationError(
                    message='Endpoint method(GET, POST etc..)'
                    'should be provided')

            if method not in DynamicHandler.SUPPORTED_METHODS:
                raise ConfigurationError(
                    message='Unsuppoterted method {}'.format(method))

            self.host_definitions[host][endpoint][method] = {'function': f}

            self.host_definitions[host][endpoint][method].update(kwargs)
            return f

        return decorator

    def on_start(self, f):
        """ Registers a function to be run on build time of application

        Function should take :class:BantApp as parameter. This is a good place
        to initialize the common objects, setting up logging vs::

            @app.on_start
            async def initialize(app):
                app.logger = logging.get("application_logger")

        """
        self.on_start_funcs.append(f)
        return f

    def before_request(self, f):
        """Registers a function to run before each request handler.

        Function should take 2 argument, an instance of
        :class:`~handler.DynamicHandler` and dictionary
        of endpoint definition::

            @app.before_request
            async def check_authorization(handler, handler_definition):
                if not handler.request.headers.get('Authorization', None):
                    raise UnauthorizedAccessError()
        """
        self.before_request_funcs.append(f)
        return f

    def after_request(self, f):
        """Registers a function to run after each request handler.

        Function should take 2 argument an instance of
        :class:`handler.DynamicHandler` and :type:`dict`
        of endpoint definition::

            @app.after_request
            async def add_cors_headers
                handler.set_header("Allow-Origin", "*")

        It's important to know that, if any error raised during pipeline,
        after request functions WILL NOT BE EXECUTED.

        To execute a function after pipeline in every circumstances, use
        :meth:`teardown_request`
        """
        self.after_request_funcs.append(f)
        return f

    def error_handler(self, err_type=None):
        """Registers a function for given error type.::

            @app.error_handler(MongoError)
            async def handle_mongo_error(handler, error, endpoint_definition):
                handler.clear()
                handler.write("Internal error occured")
                handler.set_status(500)

        :param err_type: an exception type which will be handled by this
                         error handler function. If given parameter is None,
                         handler will be used as default error handler.
        """
        def decorator(f):
            self.error_handlers[err_type] = f
            return f

        return decorator

    def on_teardown_request(self, f):
        self.teardown_request_funcs.append(f)
        return f

    def serve_static_file(self, pattern, path):
        """Serves matched files from given path:

        app.serve_static_file("*.png", "/path/to/png/files")
        """
        if not pattern:
            raise ValueError('Pattern should be specified...')

        if path is None:
            raise ValueError('Path should be specified.')

        self.static_file_handler_definitions.append((pattern, {'path': path}))

    def build_app(self, host="0.0.0.0"):
        """ Building application means, creation of
        :class:`tornado.web.Application` instance, creation of
        :class:`handler.DynamicHandler` routes, adding routes
        into tornado application, registration of
        :class:`tornado.web.StaticFileHandler`s
        """
        self.app = Application(default_host=host, **self.settings)
        app_ctx = self._build_app_ctx()

        for host, host_definition in self.host_definitions.items():
            handlers = []
            for endpoint, endpoint_definition in host_definition.items():
                handler = self._create_dynamic_handlers(
                    host, endpoint, endpoint_definition, app_ctx)
                handlers.append(*handler[1])
            self.app.add_handlers(host, handlers)

        for url_patttern, static_file_handler_settings \
                in self.static_file_handler_definitions:

            self.app.add_handlers(".*$", [
                (url_patttern, StaticFileHandler, static_file_handler_settings)
            ])

        self.is_builded = True

    def _create_dynamic_handlers(self, host, endpoint, endpoint_definition,
                                 app_ctx):
        """ Creates dynamic handler and sets all pipeline functions
        as a dictionary which will be injected to dynamic handler.
        """
        return host, [(endpoint, DynamicHandler,
                       dict(endpoint_definition=endpoint_definition,
                            endpoint=endpoint,
                            after_request_funcs=self.after_request_funcs,
                            error_handler_funcs=self.error_handlers,
                            before_request_funcs=self.before_request_funcs,
                            run_in_executor=self.run_in_executor,
                            teardown_request_funcs=self.teardown_request_funcs,
                            app_ctx=app_ctx))]

    def _build_app_ctx(self):
        """Creates application context object.

        This application context will be used by default
        plugins and will work as a namespace for external uses.

        Rationale behind this approach is that we don't want to clutter
        :class:`handler.DynamicHandler` instances.
        """
        return ApplicationContext()

    def run(self, port=8888, host="0.0.0.0"):
        """Starts an HTTP Server on the given port and host.

        This function also executes :attr:`on_start_funcs` and calls run
        method of :class:`scheduler.Scheduler`
        """
        if not self.is_builded:
            self.build_app(host=host)

        for on_start_func in self.on_start_funcs:
            self.ioloop.run_sync(functools.partial(on_start_func, self))

        self.scheduler.run()
        self.app.listen(port)
        self.ioloop.start()

    def run_in_executor(self, func, *args):
        """runs given function in another thread.
        """
        return futures.wrap_future(self.executor.submit(
            functools.partial(func, *args)),
                                   loop=self.ioloop.asyncio_loop)

    def add_tornado_handler(self, host_pattern, host_handlers):
        """ To add any handler which extends
        :class:`tornado.web.RequestHandler` class.

        :param host: Hostname to listen to
        :param handlers: list of tuples. Tuples are consist of URL pattern,
                         handler class, handler settings. For more information
                         please check
                         :meth:`tornado.web.Application.add_handlers`
        """
        self.app.add_handlers(host_pattern, host_handlers)
コード例 #26
0
ファイル: __init__.py プロジェクト: titom1986/SiCKRAGE
class WebServer(object):
    def __init__(self):
        super(WebServer, self).__init__()
        self.name = "TORNADO"
        self.daemon = True
        self.started = False
        self.video_root = None
        self.api_root = None
        self.app = None
        self.server = None

    def start(self):
        self.started = True

        # load languages
        tornado.locale.load_gettext_translations(sickrage.LOCALE_DIR, 'messages')

        # clear mako cache folder
        mako_cache = os.path.join(sickrage.app.cache_dir, 'mako')
        if os.path.isdir(mako_cache):
            shutil.rmtree(mako_cache)

        # video root
        if sickrage.app.config.root_dirs:
            root_dirs = sickrage.app.config.root_dirs.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]

        # web root
        if sickrage.app.config.web_root:
            sickrage.app.config.web_root = sickrage.app.config.web_root = (
                    '/' + sickrage.app.config.web_root.lstrip('/').strip('/'))

        # api root
        self.api_root = r'%s/api/%s' % (sickrage.app.config.web_root, sickrage.app.config.api_key)

        # tornado setup
        if sickrage.app.config.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (
                    sickrage.app.config.https_cert and os.path.exists(
                sickrage.app.config.https_cert)) or not (
                    sickrage.app.config.https_key and os.path.exists(sickrage.app.config.https_key)):
                if not create_https_certificates(sickrage.app.config.https_cert,
                                                 sickrage.app.config.https_key):
                    sickrage.app.log.info("Unable to create CERT/KEY files, disabling HTTPS")
                    sickrage.app.config.enable_https = False

            if not (os.path.exists(sickrage.app.config.https_cert) and os.path.exists(
                    sickrage.app.config.https_key)):
                sickrage.app.log.warning("Disabled HTTPS because of missing CERT and KEY files")
                sickrage.app.config.enable_https = False

        # Load the app
        self.app = Application(
            debug=True,
            autoreload=False,
            gzip=sickrage.app.config.web_use_gzip,
            cookie_secret=sickrage.app.config.web_cookie_secret,
            login_url='%s/login/' % sickrage.app.config.web_root)

        # Websocket handler
        self.app.add_handlers(".*$", [
            (r'%s/ws/ui' % sickrage.app.config.web_root, WebSocketUIHandler)
        ])

        # Static File Handlers
        self.app.add_handlers('.*$', [
            # api
            (r'%s(/?.*)' % self.api_root, ApiHandler),

            # redirect to home
            (r"(%s)" % sickrage.app.config.web_root, RedirectHandler,
             {"url": "%s/home" % sickrage.app.config.web_root}),

            # api key
            (r'%s/getkey(/?.*)' % sickrage.app.config.web_root, KeyHandler),

            # api builder
            (r'%s/api/builder' % sickrage.app.config.web_root, RedirectHandler,
             {"url": sickrage.app.config.web_root + '/apibuilder/'}),

            # login
            (r'%s/login(/?)' % sickrage.app.config.web_root, LoginHandler),

            # logout
            (r'%s/logout(/?)' % sickrage.app.config.web_root, LogoutHandler),

            # calendar
            (r'%s/calendar' % sickrage.app.config.web_root, CalendarHandler),

            # favicon
            (r'%s/(favicon\.ico)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'images/favicon.ico')}),

            # images
            (r'%s/images/(.*)' % sickrage.app.config.web_root, StaticImageHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'images')}),

            # css
            (r'%s/css/(.*)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'css')}),

            # scss
            (r'%s/scss/(.*)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'scss')}),

            # fonts
            (r'%s/fonts/(.*)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'fonts')}),

            # javascript
            (r'%s/js/(.*)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'js')}),

            # videos
            (r'%s/videos/(.*)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": self.video_root}),
        ])

        # Web Handlers
        self.app.add_handlers('.*$', Route.get_routes(sickrage.app.config.web_root))

        self.server = HTTPServer(self.app, xheaders=sickrage.app.config.handle_reverse_proxy)
        if sickrage.app.config.enable_https: self.server.ssl_options = {
            "certfile": sickrage.app.config.https_cert,
            "keyfile": sickrage.app.config.https_key
        }

        try:
            self.server.listen(sickrage.app.config.web_port)

            sickrage.app.log.info(
                "SiCKRAGE :: STARTED")
            sickrage.app.log.info(
                "SiCKRAGE :: VERSION:[{}]".format(sickrage.version()))
            sickrage.app.log.info(
                "SiCKRAGE :: CONFIG:[{}] [v{}]".format(sickrage.app.config_file, sickrage.app.config.config_version))
            sickrage.app.log.info(
                "SiCKRAGE :: DATABASE:[v{}]".format(sickrage.app.main_db.version))
            sickrage.app.log.info(
                "SiCKRAGE :: URL:[{}://{}:{}{}]".format(('http', 'https')[sickrage.app.config.enable_https],
                                                        sickrage.app.config.web_host, sickrage.app.config.web_port,
                                                        sickrage.app.config.web_root))

            # launch browser window
            if all([not sickrage.app.no_launch,
                    sickrage.app.config.launch_browser]) or sickrage.app.config.view_changelog:
                threading.Thread(None, lambda: launch_browser(
                    ('http', 'https')[sickrage.app.config.enable_https],
                    sickrage.app.config.web_host,
                    sickrage.app.config.web_port
                ), name="LAUNCH-BROWSER").start()
        except socket.error as e:
            sickrage.app.log.warning(e.strerror)
            raise SystemExit

    def shutdown(self):
        if self.started:
            self.started = False
            self.server.close_all_connections()
            self.server.stop()
コード例 #27
0
class srWebServer(object):
    def __init__(self):
        self.io_loop = IOLoop.instance()
        self.running = True
        self.restart = False
        self.open_browser = False

        self.port = sickrage.srConfig.WEB_PORT
        self.host = sickrage.srConfig.WEB_HOST

        # video root
        if sickrage.srConfig.ROOT_DIRS:
            root_dirs = sickrage.srConfig.ROOT_DIRS.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if sickrage.srConfig.WEB_ROOT:
            sickrage.srConfig.WEB_ROOT = sickrage.srConfig.WEB_ROOT = (
                '/' + sickrage.srConfig.WEB_ROOT.lstrip('/').strip('/'))

        # api root
        if not sickrage.srConfig.API_KEY:
            sickrage.srConfig.API_KEY = generateApiKey()
        self.api_root = r'%s/api/%s' % (sickrage.srConfig.WEB_ROOT,
                                        sickrage.srConfig.API_KEY)

        # tornado setup
        if sickrage.srConfig.ENABLE_HTTPS:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (sickrage.srConfig.HTTPS_CERT
                    and os.path.exists(sickrage.srConfig.HTTPS_CERT)) or not (
                        sickrage.srConfig.HTTPS_KEY
                        and os.path.exists(sickrage.srConfig.HTTPS_KEY)):
                if not create_https_certificates(sickrage.srConfig.HTTPS_CERT,
                                                 sickrage.srConfig.HTTPS_KEY):
                    sickrage.srLogger.info(
                        "Unable to create CERT/KEY files, disabling HTTPS")
                    sickrage.srConfig.ENABLE_HTTPS = False

            if not (os.path.exists(sickrage.srConfig.HTTPS_CERT)
                    and os.path.exists(sickrage.srConfig.HTTPS_KEY)):
                sickrage.srLogger.warning(
                    "Disabled HTTPS because of missing CERT and KEY files")
                sickrage.srConfig.ENABLE_HTTPS = False

        # Load the app
        self.app = Application(
            [],
            debug=sickrage.srConfig.DEBUG,
            autoreload=False,
            gzip=sickrage.srConfig.WEB_USE_GZIP,
            xheaders=sickrage.srConfig.HANDLE_REVERSE_PROXY,
            cookie_secret=sickrage.srConfig.WEB_COOKIE_SECRET,
            login_url='%s/login/' % sickrage.srConfig.WEB_ROOT,
        )

        # Main Handlers
        self.app.add_handlers(
            '.*$',
            [
                # webapi handler
                (r'%s(/?.*)' % self.api_root, ApiHandler),

                # webapi key retrieval
                (r'%s/getkey(/?.*)' % sickrage.srConfig.WEB_ROOT, KeyHandler),

                # webapi builder redirect
                (r'%s/api/builder' % sickrage.srConfig.WEB_ROOT,
                 RedirectHandler, {
                     "url": sickrage.srConfig.WEB_ROOT + '/apibuilder/'
                 }),

                # webui login/logout handlers
                (r'%s/login(/?)' % sickrage.srConfig.WEB_ROOT, LoginHandler),
                (r'%s/logout(/?)' % sickrage.srConfig.WEB_ROOT, LogoutHandler),

                # webui handlers
            ] + Route.get_routes(sickrage.srConfig.WEB_ROOT))

        # Web calendar handler (Needed because option Unprotected calendar)
        self.app.add_handlers('.*$', [
            (r'%s/calendar' % sickrage.srConfig.WEB_ROOT, CalendarHandler),
        ])

        # Static File Handlers
        self.app.add_handlers(
            ".*$",
            [
                # favicon
                (r'%s/(favicon\.ico)' % sickrage.srConfig.WEB_ROOT,
                 StaticFileHandler, {
                     "path":
                     os.path.join(sickrage.srConfig.GUI_DIR,
                                  'images/ico/favicon.ico')
                 }),

                # images
                (r'%s.*?/images/(.*)' % sickrage.srConfig.WEB_ROOT,
                 StaticImageHandler, {
                     "path": os.path.join(sickrage.srConfig.GUI_DIR, 'images')
                 }),

                # css
                (r'%s/css/(.*)' % sickrage.srConfig.WEB_ROOT,
                 StaticFileHandler, {
                     "path": os.path.join(sickrage.srConfig.GUI_DIR, 'css')
                 }),

                # javascript
                (r'%s/js/(.*)' % sickrage.srConfig.WEB_ROOT, StaticFileHandler,
                 {
                     "path": os.path.join(sickrage.srConfig.GUI_DIR, 'js')
                 }),

                # videos
            ] + [(r'%s/videos/(.*)' % sickrage.srConfig.WEB_ROOT,
                  StaticFileHandler, {
                      "path": self.video_root
                  })])

    def start(self):
        threading.currentThread().setName("TORNADO")

        try:
            self.server = HTTPServer(self.app)
            if sickrage.srConfig.ENABLE_HTTPS:
                self.server.ssl_options = {
                    "certfile": sickrage.srConfig.HTTPS_CERT,
                    "keyfile": sickrage.srConfig.HTTPS_KEY
                }
            self.server.listen(self.port, self.host)

            # launch browser window
            if self.open_browser:
                threading.Thread(
                    None, lambda: launch_browser(
                        ('http', 'https')[sickrage.srConfig.ENABLE_HTTPS],
                        sickrage.srConfig.WEB_PORT, sickrage.srConfig.WEB_ROOT)
                ).start()

            sickrage.srConfig.STARTED = True

            sickrage.srLogger.info(
                "SiCKRAGE STARTED :: VERSION:[{}] CONFIG:[{}] URL:[{}://{}:{}/]"
                .format(sickrage.srCore.VERSION, sickrage.srConfig.CONFIG_FILE,
                        ('http', 'https')[sickrage.srConfig.ENABLE_HTTPS],
                        get_lan_ip(), sickrage.srConfig.WEB_PORT))

            self.io_loop.start()
        except (KeyboardInterrupt, SystemExit) as e:
            sickrage.srLogger.info('PERFORMING SHUTDOWN')
        except Exception as e:
            sickrage.srLogger.info("TORNADO failed to start: {}".format(
                e.message))
        finally:
            self.server_shutdown()
            sickrage.srLogger.shutdown()

    def server_restart(self):
        sickrage.srLogger.info('PERFORMING RESTART')
        import tornado.autoreload
        tornado.autoreload.add_reload_hook(self.server_shutdown)
        tornado.autoreload.start()
        tornado.autoreload._reload()

    def server_shutdown(self):
        self.server.stop()
        if self.running:
            self.io_loop.stop()

        # shutdown sickrage
        if sickrage.srCore.STARTED:
            sickrage.srCore.halt()
            sickrage.srCore.save_all()

        sickrage.srLogger.info('SHUTDOWN COMPLETED!')
コード例 #28
0
ファイル: core.py プロジェクト: pymedusa/SickRage
class AppWebServer(threading.Thread):
    def __init__(self, options=None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.alive = True
        self.name = 'TORNADO'

        self.options = options or {}
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', '/')
        assert isinstance(self.options['port'], int)
        assert 'data_root' in self.options

        self.server = None
        self.io_loop = None

        # video root
        if app.ROOT_DIRS:
            root_dirs = app.ROOT_DIRS
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if self.options['web_root']:
            app.WEB_ROOT = self.options['web_root'] = clean_url_path(self.options['web_root'])

        # Configure root to selected theme.
        app.WEB_ROOT = self.options['theme_path'] = clean_url_path(app.WEB_ROOT)

        # Configure the directory to the theme's data root.
        app.THEME_DATA_ROOT = self.options['theme_data_root'] = os.path.join(self.options['data_root'], app.THEME_NAME)

        # api root
        if not app.API_KEY:
            app.API_KEY = generate_api_key()
        self.options['api_root'] = r'{root}/api/(?:v1/)?{key}'.format(root=app.WEB_ROOT, key=app.API_KEY)
        self.options['api_v2_root'] = r'{root}/api/v2'.format(root=app.WEB_ROOT)

        # websocket root
        self.options['web_socket'] = r'{root}/ws'.format(root=app.WEB_ROOT)

        # tornado setup
        self.enable_https = self.options['enable_https']
        self.https_cert = self.options['https_cert']
        self.https_key = self.options['https_key']

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert and os.path.exists(self.https_cert)) or not (
                    self.https_key and os.path.exists(self.https_key)):
                if not create_https_certificates(self.https_cert, self.https_key):
                    log.info('Unable to create CERT/KEY files, disabling HTTPS')
                    app.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (os.path.exists(self.https_cert) and os.path.exists(self.https_key)):
                log.warning('Disabled HTTPS because of missing CERT and KEY files')
                app.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application(
            [],
            debug=True,
            autoreload=False,
            gzip=app.WEB_USE_GZIP,
            xheaders=app.HANDLE_REVERSE_PROXY,
            cookie_secret=app.WEB_COOKIE_SECRET,
            login_url=r'{root}/login/'.format(root=self.options['theme_path']),
            log_function=self.log_request,
        )

        self.app.add_handlers('.*$', get_apiv2_handlers(self.options['api_v2_root']))

        # Websocket handler
        self.app.add_handlers('.*$', [
            (r'{base}/ui(/?.*)'.format(base=self.options['web_socket']), WebSocketUIHandler)
        ])

        # Static File Handlers
        self.app.add_handlers('.*$', [
            # favicon
            (r'{base}/favicon\.ico()'.format(base=self.options['theme_path']), StaticFileHandler,
             {'path': os.path.join(self.options['theme_data_root'], 'assets', 'img', 'ico', 'favicon.ico')}),

            # images
            (r'{base}/images/(.*)'.format(base=self.options['theme_path']), StaticFileHandler,
             {'path': os.path.join(self.options['theme_data_root'], 'assets', 'img')}),

            # cached images
            (r'{base}/cache/images/(.*)'.format(base=self.options['theme_path']), StaticFileHandler,
             {'path': os.path.join(app.CACHE_DIR, 'images')}),

            # css
            (r'{base}/css/(.*)'.format(base=self.options['theme_path']), StaticFileHandler,
             {'path': os.path.join(self.options['theme_data_root'], 'assets', 'css')}),

            # javascript
            (r'{base}/js/(.*)'.format(base=self.options['theme_path']), StaticFileHandler,
             {'path': os.path.join(self.options['theme_data_root'], 'assets', 'js')}),

            # fonts
            (r'{base}/fonts/(.*)'.format(base=self.options['theme_path']), StaticFileHandler,
             {'path': os.path.join(self.options['theme_data_root'], 'assets', 'fonts')}),

            # videos
            (r'{base}/videos/(.*)'.format(base=self.options['theme_path']), StaticFileHandler,
             {'path': self.video_root}),

            # vue dist
            (r'{base}/vue/dist/(.*)'.format(base=self.options['theme_path']), StaticFileHandler,
             {'path': os.path.join(self.options['theme_data_root'], 'vue')}),

            # vue index.html
            (r'{base}/vue/?.*()'.format(base=self.options['theme_path']), AuthenticatedStaticFileHandler,
             {'path': os.path.join(self.options['theme_data_root'], 'index.html'), 'default_filename': 'index.html'}),
        ])

        # Used for hot-swapping themes
        # This is the 2nd rule from the end, because the last one is always `self.app.wildcard_router`
        self.app.static_file_handlers = self.app.default_router.rules[-2]

        # API v1 handlers
        self.app.add_handlers('.*$', [
            # Main handler
            (r'{base}(/?.*)'.format(base=self.options['api_root']), ApiHandler),

            # Key retrieval
            (r'{base}/getkey(/?.*)'.format(base=self.options['web_root']), KeyHandler),

            # Builder redirect
            (r'{base}/api/builder'.format(base=self.options['web_root']),
             RedirectHandler, {'url': '{base}/apibuilder/'.format(base=self.options['web_root'])}),

            # Webui login/logout handlers
            (r'{base}/login(/?)'.format(base=self.options['theme_path']), LoginHandler),
            (r'{base}/logout(/?)'.format(base=self.options['theme_path']), LogoutHandler),

            (r'{base}/token(/?)'.format(base=self.options['web_root']), TokenHandler),

            # Web calendar handler (Needed because option Unprotected calendar)
            (r'{base}/calendar'.format(base=self.options['web_root']), CalendarHandler),

            # webui handlers
        ] + self._get_webui_routes())

    def _get_webui_routes(self):
        webroot = self.options['theme_path']
        route._routes = list(reversed([url(webroot + u.regex.pattern, u.handler_class, u.kwargs, u.name) for u in route.get_routes()]))
        return route.get_routes()

    def run(self):
        # Start event loop in python3
        if six.PY3:
            import asyncio
            asyncio.set_event_loop(asyncio.new_event_loop())

        if self.enable_https:
            protocol = 'https'
            self.server = HTTPServer(self.app, ssl_options={'certfile': self.https_cert, 'keyfile': self.https_key})
        else:
            protocol = 'http'
            self.server = HTTPServer(self.app)

        log.info('Starting Medusa on {scheme}://{host}:{port}{web_root}/', {
            'scheme': protocol, 'host': self.options['host'],
            'port': self.options['port'], 'web_root': self.options['theme_path']
        })

        try:
            self.server.listen(self.options['port'], self.options['host'])
        except Exception as ex:
            if app.LAUNCH_BROWSER and not self.daemon:
                app.instance.launch_browser('https' if app.ENABLE_HTTPS else 'http', self.options['port'], app.WEB_ROOT)
                log.info('Launching browser and exiting')
            log.info('Could not start the web server on port {port}. Exception: {ex}', {
                'port': self.options['port'],
                'ex': ex
            })
            os._exit(1)  # pylint: disable=protected-access

        try:
            self.io_loop = IOLoop.current()
            self.io_loop.start()
        except (IOError, ValueError):
            # Ignore errors like 'ValueError: I/O operation on closed kqueue fd'. These might be thrown during a reload.
            pass

    def shutDown(self):
        self.alive = False
        self.io_loop.stop()

    def log_request(self, handler):
        """
        Write a completed HTTP request to the logs.

        This method handles logging Tornado requests.
        """
        if not app.WEB_LOG:
            return

        if handler.get_status() < 400:
            level = logging.INFO
        elif handler.get_status() < 500:
            # Don't log normal RESTful responses as warnings
            if isinstance(handler, BaseRequestHandler):
                level = logging.INFO
            else:
                level = logging.WARNING
        else:
            level = logging.ERROR

        log.log(
            level,
            '{status} {summary} {time:.2f}ms',
            {
                'status': handler.get_status(),
                'summary': handler._request_summary(),
                'time': 1000.0 * handler.request.request_time()
            }
        )
コード例 #29
0
ファイル: runner.py プロジェクト: mtab3000/CouchPotatoServer
def runCouchPotato(options, base_path, args, data_dir = None, log_dir = None, Env = None, desktop = None):

    try:
        locale.setlocale(locale.LC_ALL, "")
        encoding = locale.getpreferredencoding()
    except (locale.Error, IOError):
        encoding = None

    # for OSes that are poorly configured I'll just force UTF-8
    if not encoding or encoding in ('ANSI_X3.4-1968', 'US-ASCII', 'ASCII'):
        encoding = 'UTF-8'

    Env.set('encoding', encoding)

    # Do db stuff
    db_path = toUnicode(os.path.join(data_dir, 'couchpotato.db'))

    # Backup before start and cleanup old databases
    new_backup = toUnicode(os.path.join(data_dir, 'db_backup', str(int(time.time()))))

    # Create path and copy
    if not os.path.isdir(new_backup): os.makedirs(new_backup)
    src_files = [options.config_file, db_path, db_path + '-shm', db_path + '-wal']
    for src_file in src_files:
        if os.path.isfile(src_file):
            dst_file = toUnicode(os.path.join(new_backup, os.path.basename(src_file)))
            shutil.copyfile(src_file, dst_file)

            # Try and copy stats seperately
            try: shutil.copystat(src_file, dst_file)
            except: pass

    # Remove older backups, keep backups 3 days or at least 3
    backups = []
    for directory in os.listdir(os.path.dirname(new_backup)):
        backup = toUnicode(os.path.join(os.path.dirname(new_backup), directory))
        if os.path.isdir(backup):
            backups.append(backup)

    total_backups = len(backups)
    for backup in backups:
        if total_backups > 3:
            if tryInt(os.path.basename(backup)) < time.time() - 259200:
                for the_file in os.listdir(backup):
                    file_path = os.path.join(backup, the_file)
                    try:
                        if os.path.isfile(file_path):
                            os.remove(file_path)
                    except:
                        raise

                os.rmdir(backup)
                total_backups -= 1


    # Register environment settings
    Env.set('app_dir', toUnicode(base_path))
    Env.set('data_dir', toUnicode(data_dir))
    Env.set('log_path', toUnicode(os.path.join(log_dir, 'CouchPotato.log')))
    Env.set('db_path', toUnicode('sqlite:///' + db_path))
    Env.set('cache_dir', toUnicode(os.path.join(data_dir, 'cache')))
    Env.set('cache', FileSystemCache(toUnicode(os.path.join(Env.get('cache_dir'), 'python'))))
    Env.set('console_log', options.console_log)
    Env.set('quiet', options.quiet)
    Env.set('desktop', desktop)
    Env.set('daemonized', options.daemon)
    Env.set('args', args)
    Env.set('options', options)

    # Determine debug
    debug = options.debug or Env.setting('debug', default = False, type = 'bool')
    Env.set('debug', debug)

    # Development
    development = Env.setting('development', default = False, type = 'bool')
    Env.set('dev', development)

    # Disable logging for some modules
    for logger_name in ['enzyme', 'guessit', 'subliminal', 'apscheduler']:
        logging.getLogger(logger_name).setLevel(logging.ERROR)

    for logger_name in ['gntp', 'migrate']:
        logging.getLogger(logger_name).setLevel(logging.WARNING)

    # Use reloader
    reloader = debug is True and development and not Env.get('desktop') and not options.daemon

    # Logger
    logger = logging.getLogger()
    formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', '%m-%d %H:%M:%S')
    level = logging.DEBUG if debug else logging.INFO
    logger.setLevel(level)
    logging.addLevelName(19, 'INFO')

    # To screen
    if (debug or options.console_log) and not options.quiet and not options.daemon:
        hdlr = logging.StreamHandler(sys.stderr)
        hdlr.setFormatter(formatter)
        logger.addHandler(hdlr)

    # To file
    hdlr2 = handlers.RotatingFileHandler(Env.get('log_path'), 'a', 500000, 10)
    hdlr2.setFormatter(formatter)
    logger.addHandler(hdlr2)

    # Start logging & enable colors
    import color_logs
    from couchpotato.core.logger import CPLog
    log = CPLog(__name__)
    log.debug('Started with options %s', options)

    def customwarn(message, category, filename, lineno, file = None, line = None):
        log.warning('%s %s %s line:%s', (category, message, filename, lineno))
    warnings.showwarning = customwarn

    # Check if database exists
    db = Env.get('db_path')
    db_exists = os.path.isfile(toUnicode(db_path))

    # Load migrations
    if db_exists:

        from migrate.versioning.api import version_control, db_version, version, upgrade
        repo = os.path.join(base_path, 'couchpotato', 'core', 'migration')

        latest_db_version = version(repo)
        try:
            current_db_version = db_version(db, repo)
        except:
            version_control(db, repo, version = latest_db_version)
            current_db_version = db_version(db, repo)

        if current_db_version < latest_db_version:
            if development:
                log.error('There is a database migration ready, but you are running development mode, so it won\'t be used. If you see this, you are stupid. Please disable development mode.')
            else:
                log.info('Doing database upgrade. From %d to %d', (current_db_version, latest_db_version))
                upgrade(db, repo)

    # Configure Database
    from couchpotato.core.settings.model import setup
    setup()

    # Create app
    from couchpotato import WebHandler
    web_base = ('/' + Env.setting('url_base').lstrip('/') + '/') if Env.setting('url_base') else '/'
    Env.set('web_base', web_base)

    api_key = Env.setting('api_key')
    api_base = r'%sapi/%s/' % (web_base, api_key)
    Env.set('api_base', api_base)

    # Basic config
    host = Env.setting('host', default = '0.0.0.0')
    # app.debug = development
    config = {
        'use_reloader': reloader,
        'port': tryInt(Env.setting('port', default = 5050)),
        'host': host if host and len(host) > 0 else '0.0.0.0',
        'ssl_cert': Env.setting('ssl_cert', default = None),
        'ssl_key': Env.setting('ssl_key', default = None),
    }


    # Load the app
    application = Application([],
        log_function = lambda x : None,
        debug = config['use_reloader'],
        gzip = True,
        cookie_secret = api_key,
        login_url = '%slogin/' % web_base,
    )
    Env.set('app', application)

    # Request handlers
    application.add_handlers(".*$", [
        (r'%snonblock/(.*)(/?)' % api_base, NonBlockHandler),

        # API handlers
        (r'%s(.*)(/?)' % api_base, ApiHandler), # Main API handler
        (r'%sgetkey(/?)' % web_base, KeyHandler), # Get API key
        (r'%s' % api_base, RedirectHandler, {"url": web_base + 'docs/'}), # API docs

        # Login handlers
        (r'%slogin(/?)' % web_base, LoginHandler),
        (r'%slogout(/?)' % web_base, LogoutHandler),

        # Catch all webhandlers
        (r'%s(.*)(/?)' % web_base, WebHandler),
        (r'(.*)', WebHandler),
    ])

    # Static paths
    static_path = '%sstatic/' % web_base
    for dir_name in ['fonts', 'images', 'scripts', 'style']:
        application.add_handlers(".*$", [
             ('%s%s/(.*)' % (static_path, dir_name), StaticFileHandler, {'path': toUnicode(os.path.join(base_path, 'couchpotato', 'static', dir_name))})
        ])
    Env.set('static_path', static_path)


    # Load configs & plugins
    loader = Env.get('loader')
    loader.preload(root = toUnicode(base_path))
    loader.run()


    # Fill database with needed stuff
    if not db_exists:
        fireEvent('app.initialize', in_order = True)


    # Go go go!
    from tornado.ioloop import IOLoop
    loop = IOLoop.current()


    # Some logging and fire load event
    try: log.info('Starting server on port %(port)s', config)
    except: pass
    fireEventAsync('app.load')


    if config['ssl_cert'] and config['ssl_key']:
        server = HTTPServer(application, no_keep_alive = True, ssl_options = {
           "certfile": config['ssl_cert'],
           "keyfile": config['ssl_key'],
        })
    else:
        server = HTTPServer(application, no_keep_alive = True)

    try_restart = True
    restart_tries = 5

    while try_restart:
        try:
            server.listen(config['port'], config['host'])
            loop.start()
        except Exception, e:
            log.error('Failed starting: %s', traceback.format_exc())
            try:
                nr, msg = e
                if nr == 48:
                    log.info('Port (%s) needed for CouchPotato is already in use, try %s more time after few seconds', (config.get('port'), restart_tries))
                    time.sleep(1)
                    restart_tries -= 1

                    if restart_tries > 0:
                        continue
                    else:
                        return
            except:
                pass

            raise

        try_restart = False
コード例 #30
0
ファイル: __init__.py プロジェクト: newrain7803/SiCKRAGE
class WebServer(threading.Thread):
    def __init__(self):
        super(WebServer, self).__init__()
        self.name = "TORNADO"
        self.daemon = True
        self.started = False
        self.video_root = None
        self.api_root = None
        self.app = None
        self.server = None
        self.io_loop = None

    def run(self):
        self.started = True
        self.io_loop = IOLoop()

        # load languages
        tornado.locale.load_gettext_translations(sickrage.LOCALE_DIR, 'messages')

        # Check configured web port is correct
        if sickrage.app.config.web_port < 21 or sickrage.app.config.web_port > 65535:
            sickrage.app.config.web_port = 8081

        # clear mako cache folder
        mako_cache = os.path.join(sickrage.app.cache_dir, 'mako')
        if os.path.isdir(mako_cache):
            shutil.rmtree(mako_cache, ignore_errors=True)

        # video root
        if sickrage.app.config.root_dirs:
            root_dirs = sickrage.app.config.root_dirs.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]

        # web root
        if sickrage.app.config.web_root:
            sickrage.app.config.web_root = sickrage.app.config.web_root = (
                    '/' + sickrage.app.config.web_root.lstrip('/').strip('/'))

        # api root
        self.api_root = r'%s/api/%s' % (sickrage.app.config.web_root, sickrage.app.config.api_key)

        # tornado setup
        if sickrage.app.config.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not create_https_certificates(sickrage.app.config.https_cert, sickrage.app.config.https_key):
                sickrage.app.log.info("Unable to create CERT/KEY files, disabling HTTPS")
                sickrage.app.config.enable_https = False

            if not (os.path.exists(sickrage.app.config.https_cert) and os.path.exists(sickrage.app.config.https_key)):
                sickrage.app.log.warning("Disabled HTTPS because of missing CERT and KEY files")
                sickrage.app.config.enable_https = False

        # Load templates
        mako_lookup = TemplateLookup(
            directories=[sickrage.app.config.gui_views_dir],
            module_directory=os.path.join(sickrage.app.cache_dir, 'mako'),
            filesystem_checks=True,
            strict_undefined=True,
            input_encoding='utf-8',
            output_encoding='utf-8',
            encoding_errors='replace'
        )

        templates = {}
        for root, dirs, files in os.walk(sickrage.app.config.gui_views_dir):
            path = root.split(os.sep)

            for x in sickrage.app.config.gui_views_dir.split(os.sep):
                if x in path:
                    del path[path.index(x)]

            for file in files:
                filename = '{}/{}'.format('/'.join(path), file).lstrip('/')
                templates[filename] = mako_lookup.get_template(filename)

        # Load the app
        self.app = Application(
            debug=True,
            autoreload=False,
            gzip=sickrage.app.config.web_use_gzip,
            cookie_secret=sickrage.app.config.web_cookie_secret,
            login_url='%s/login/' % sickrage.app.config.web_root,
            templates=templates,
            default_handler_class=NotFoundHandler
        )

        # Websocket handler
        self.app.add_handlers('.*$', [
            (r'%s/ws/ui' % sickrage.app.config.web_root, WebSocketUIHandler)
        ])

        # Static File Handlers
        self.app.add_handlers('.*$', [
            # api
            (r'%s/api/(\w{32})(/?.*)' % sickrage.app.config.web_root, ApiHandler),

            # redirect to home
            (r"(%s)(/?)" % sickrage.app.config.web_root, RedirectHandler,
             {"url": "%s/home" % sickrage.app.config.web_root}),

            # api builder
            (r'%s/api/builder' % sickrage.app.config.web_root, RedirectHandler,
             {"url": sickrage.app.config.web_root + '/apibuilder/'}),

            # login
            (r'%s/login(/?)' % sickrage.app.config.web_root, LoginHandler),

            # logout
            (r'%s/logout(/?)' % sickrage.app.config.web_root, LogoutHandler),

            # favicon
            (r'%s/(favicon\.ico)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'images/favicon.ico')}),

            # images
            (r'%s/images/(.*)' % sickrage.app.config.web_root, StaticImageHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'images')}),

            # css
            (r'%s/css/(.*)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'css')}),

            # scss
            (r'%s/scss/(.*)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'scss')}),

            # fonts
            (r'%s/fonts/(.*)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'fonts')}),

            # javascript
            (r'%s/js/(.*)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'js')}),

            # videos
            (r'%s/videos/(.*)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": self.video_root}),
        ])

        # Handlers
        self.app.add_handlers('.*$', [
            (r'%s/robots.txt' % sickrage.app.config.web_root, RobotsDotTxtHandler),
            (r'%s/messages.po' % sickrage.app.config.web_root, MessagesDotPoHandler),
            (r'%s/quicksearch.json' % sickrage.app.config.web_root, QuicksearchDotJsonHandler),
            (r'%s/apibuilder(/?)' % sickrage.app.config.web_root, APIBulderHandler),
            (r'%s/setHomeLayout(/?)' % sickrage.app.config.web_root, SetHomeLayoutHandler),
            (r'%s/setPosterSortBy(/?)' % sickrage.app.config.web_root, SetPosterSortByHandler),
            (r'%s/setPosterSortDir(/?)' % sickrage.app.config.web_root, SetPosterSortDirHandler),
            (r'%s/setHistoryLayout(/?)' % sickrage.app.config.web_root, SetHistoryLayoutHandler),
            (r'%s/toggleDisplayShowSpecials(/?)' % sickrage.app.config.web_root, ToggleDisplayShowSpecialsHandler),
            (r'%s/toggleScheduleDisplayPaused(/?)' % sickrage.app.config.web_root, ToggleScheduleDisplayPausedHandler),
            (r'%s/setScheduleSort(/?)' % sickrage.app.config.web_root, SetScheduleSortHandler),
            (r'%s/forceSchedulerJob(/?)' % sickrage.app.config.web_root, ForceSchedulerJobHandler),
            (r'%s/announcements(/?)' % sickrage.app.config.web_root, AnnouncementsHandler),
            (r'%s/announcements/announcementCount(/?)' % sickrage.app.config.web_root, AnnouncementCountHandler),
            (r'%s/announcements/mark-seen(/?)' % sickrage.app.config.web_root, MarkAnnouncementSeenHandler),
            (r'%s/schedule(/?)' % sickrage.app.config.web_root, ScheduleHandler),
            (r'%s/setScheduleLayout(/?)' % sickrage.app.config.web_root, SetScheduleLayoutHandler),
            (r'%s/calendar(/?)' % sickrage.app.config.web_root, CalendarHandler),
            (r'%s/changelog(/?)' % sickrage.app.config.web_root, ChangelogHandler),
            (r'%s/account/link(/?)' % sickrage.app.config.web_root, AccountLinkHandler),
            (r'%s/account/unlink(/?)' % sickrage.app.config.web_root, AccountUnlinkHandler),
            (r'%s/account/is-linked(/?)' % sickrage.app.config.web_root, AccountIsLinkedHandler),
            (r'%s/history(/?)' % sickrage.app.config.web_root, HistoryHandler),
            (r'%s/history/clear(/?)' % sickrage.app.config.web_root, HistoryClearHandler),
            (r'%s/history/trim(/?)' % sickrage.app.config.web_root, HistoryTrimHandler),
            (r'%s/irc(/?)' % sickrage.app.config.web_root, IRCHandler),
            (r'%s/logs(/?)' % sickrage.app.config.web_root, LogsHandler),
            (r'%s/logs/errorCount(/?)' % sickrage.app.config.web_root, ErrorCountHandler),
            (r'%s/logs/warningCount(/?)' % sickrage.app.config.web_root, WarningCountHandler),
            (r'%s/logs/view(/?)' % sickrage.app.config.web_root, LogsViewHandler),
            (r'%s/logs/clearAll(/?)' % sickrage.app.config.web_root, LogsClearAllHanlder),
            (r'%s/logs/clearWarnings(/?)' % sickrage.app.config.web_root, LogsClearWarningsHanlder),
            (r'%s/logs/clearErrors(/?)' % sickrage.app.config.web_root, LogsClearErrorsHanlder),
            (r'%s/browser(/?)' % sickrage.app.config.web_root, WebFileBrowserHandler),
            (r'%s/browser/complete(/?)' % sickrage.app.config.web_root, WebFileBrowserCompleteHandler),
            (r'%s/home(/?)' % sickrage.app.config.web_root, HomeHandler),
            (r'%s/home/showProgress(/?)' % sickrage.app.config.web_root, ShowProgressHandler),
            (r'%s/home/is-alive(/?)' % sickrage.app.config.web_root, IsAliveHandler),
            (r'%s/home/testSABnzbd(/?)' % sickrage.app.config.web_root, TestSABnzbdHandler),
            (r'%s/home/testSynologyDSM(/?)' % sickrage.app.config.web_root, TestSynologyDSMHandler),
            (r'%s/home/testTorrent(/?)' % sickrage.app.config.web_root, TestTorrentHandler),
            (r'%s/home/testFreeMobile(/?)' % sickrage.app.config.web_root, TestFreeMobileHandler),
            (r'%s/home/testTelegram(/?)' % sickrage.app.config.web_root, TestTelegramHandler),
            (r'%s/home/testJoin(/?)' % sickrage.app.config.web_root, TestJoinHandler),
            (r'%s/home/testGrowl(/?)' % sickrage.app.config.web_root, TestGrowlHandler),
            (r'%s/home/testProwl(/?)' % sickrage.app.config.web_root, TestProwlHandler),
            (r'%s/home/testBoxcar2(/?)' % sickrage.app.config.web_root, TestBoxcar2Handler),
            (r'%s/home/testPushover(/?)' % sickrage.app.config.web_root, TestPushoverHandler),
            (r'%s/home/twitterStep1(/?)' % sickrage.app.config.web_root, TwitterStep1Handler),
            (r'%s/home/twitterStep2(/?)' % sickrage.app.config.web_root, TwitterStep2Handler),
            (r'%s/home/testTwitter(/?)' % sickrage.app.config.web_root, TestTwitterHandler),
            (r'%s/home/testTwilio(/?)' % sickrage.app.config.web_root, TestTwilioHandler),
            (r'%s/home/testSlack(/?)' % sickrage.app.config.web_root, TestSlackHandler),
            (r'%s/home/testAlexa(/?)' % sickrage.app.config.web_root, TestAlexaHandler),
            (r'%s/home/testDiscord(/?)' % sickrage.app.config.web_root, TestDiscordHandler),
            (r'%s/home/testKODI(/?)' % sickrage.app.config.web_root, TestKODIHandler),
            (r'%s/home/testPMC(/?)' % sickrage.app.config.web_root, TestPMCHandler),
            (r'%s/home/testPMS(/?)' % sickrage.app.config.web_root, TestPMSHandler),
            (r'%s/home/testLibnotify(/?)' % sickrage.app.config.web_root, TestLibnotifyHandler),
            (r'%s/home/testEMBY(/?)' % sickrage.app.config.web_root, TestEMBYHandler),
            (r'%s/home/testNMJ(/?)' % sickrage.app.config.web_root, TestNMJHandler),
            (r'%s/home/settingsNMJ(/?)' % sickrage.app.config.web_root, SettingsNMJHandler),
            (r'%s/home/testNMJv2(/?)' % sickrage.app.config.web_root, TestNMJv2Handler),
            (r'%s/home/settingsNMJv2(/?)' % sickrage.app.config.web_root, SettingsNMJv2Handler),
            (r'%s/home/getTraktToken(/?)' % sickrage.app.config.web_root, GetTraktTokenHandler),
            (r'%s/home/testTrakt(/?)' % sickrage.app.config.web_root, TestTraktHandler),
            (r'%s/home/loadShowNotifyLists(/?)' % sickrage.app.config.web_root, LoadShowNotifyListsHandler),
            (r'%s/home/saveShowNotifyList(/?)' % sickrage.app.config.web_root, SaveShowNotifyListHandler),
            (r'%s/home/testEmail(/?)' % sickrage.app.config.web_root, TestEmailHandler),
            (r'%s/home/testNMA(/?)' % sickrage.app.config.web_root, TestNMAHandler),
            (r'%s/home/testPushalot(/?)' % sickrage.app.config.web_root, TestPushalotHandler),
            (r'%s/home/testPushbullet(/?)' % sickrage.app.config.web_root, TestPushbulletHandler),
            (r'%s/home/getPushbulletDevices(/?)' % sickrage.app.config.web_root, GetPushbulletDevicesHandler),
            (r'%s/home/serverStatus(/?)' % sickrage.app.config.web_root, ServerStatusHandler),
            (r'%s/home/providerStatus(/?)' % sickrage.app.config.web_root, ProviderStatusHandler),
            (r'%s/home/shutdown(/?)' % sickrage.app.config.web_root, ShutdownHandler),
            (r'%s/home/restart(/?)' % sickrage.app.config.web_root, RestartHandler),
            (r'%s/home/updateCheck(/?)' % sickrage.app.config.web_root, UpdateCheckHandler),
            (r'%s/home/update(/?)' % sickrage.app.config.web_root, UpdateHandler),
            (r'%s/home/verifyPath(/?)' % sickrage.app.config.web_root, VerifyPathHandler),
            (r'%s/home/installRequirements(/?)' % sickrage.app.config.web_root, InstallRequirementsHandler),
            (r'%s/home/branchCheckout(/?)' % sickrage.app.config.web_root, BranchCheckoutHandler),
            (r'%s/home/displayShow(/?)' % sickrage.app.config.web_root, DisplayShowHandler),
            (r'%s/home/togglePause(/?)' % sickrage.app.config.web_root, TogglePauseHandler),
            (r'%s/home/deleteShow' % sickrage.app.config.web_root, DeleteShowHandler),
            (r'%s/home/refreshShow(/?)' % sickrage.app.config.web_root, RefreshShowHandler),
            (r'%s/home/updateShow(/?)' % sickrage.app.config.web_root, UpdateShowHandler),
            (r'%s/home/subtitleShow(/?)' % sickrage.app.config.web_root, SubtitleShowHandler),
            (r'%s/home/updateKODI(/?)' % sickrage.app.config.web_root, UpdateKODIHandler),
            (r'%s/home/updatePLEX(/?)' % sickrage.app.config.web_root, UpdatePLEXHandler),
            (r'%s/home/updateEMBY(/?)' % sickrage.app.config.web_root, UpdateEMBYHandler),
            (r'%s/home/syncTrakt(/?)' % sickrage.app.config.web_root, SyncTraktHandler),
            (r'%s/home/deleteEpisode(/?)' % sickrage.app.config.web_root, DeleteEpisodeHandler),
            (r'%s/home/testRename(/?)' % sickrage.app.config.web_root, TestRenameHandler),
            (r'%s/home/doRename(/?)' % sickrage.app.config.web_root, DoRenameHandler),
            (r'%s/home/searchEpisode(/?)' % sickrage.app.config.web_root, SearchEpisodeHandler),
            (r'%s/home/getManualSearchStatus(/?)' % sickrage.app.config.web_root, GetManualSearchStatusHandler),
            (r'%s/home/searchEpisodeSubtitles(/?)' % sickrage.app.config.web_root, SearchEpisodeSubtitlesHandler),
            (r'%s/home/setSceneNumbering(/?)' % sickrage.app.config.web_root, SetSceneNumberingHandler),
            (r'%s/home/retryEpisode(/?)' % sickrage.app.config.web_root, RetryEpisodeHandler),
            (r'%s/home/fetch_releasegroups(/?)' % sickrage.app.config.web_root, FetchReleasegroupsHandler),
            (r'%s/home/postprocess(/?)' % sickrage.app.config.web_root, HomePostProcessHandler),
            (r'%s/home/postprocess/processEpisode(/?)' % sickrage.app.config.web_root, HomeProcessEpisodeHandler),
            (r'%s/home/addShows(/?)' % sickrage.app.config.web_root, HomeAddShowsHandler),
            (r'%s/home/addShows/searchIndexersForShowName(/?)' % sickrage.app.config.web_root, SearchIndexersForShowNameHandler),
            (r'%s/home/addShows/massAddTable(/?)' % sickrage.app.config.web_root, MassAddTableHandler),
            (r'%s/home/addShows/newShow(/?)' % sickrage.app.config.web_root, NewShowHandler),
            (r'%s/home/addShows/traktShows(/?)' % sickrage.app.config.web_root, TraktShowsHandler),
            (r'%s/home/addShows/popularShows(/?)' % sickrage.app.config.web_root, PopularShowsHandler),
            (r'%s/home/addShows/addShowToBlacklist(/?)' % sickrage.app.config.web_root, AddShowToBlacklistHandler),
            (r'%s/home/addShows/existingShows(/?)' % sickrage.app.config.web_root, ExistingShowsHandler),
            (r'%s/home/addShows/addShowByID(/?)' % sickrage.app.config.web_root, AddShowByIDHandler),
            (r'%s/home/addShows/addNewShow(/?)' % sickrage.app.config.web_root, AddNewShowHandler),
            (r'%s/home/addShows/addExistingShows(/?)' % sickrage.app.config.web_root, AddExistingShowsHandler),
            (r'%s/manage(/?)' % sickrage.app.config.web_root, ManageHandler),
            (r'%s/manage/editShow(/?)' % sickrage.app.config.web_root, EditShowHandler),
            (r'%s/manage/showEpisodeStatuses(/?)' % sickrage.app.config.web_root, ShowEpisodeStatusesHandler),
            (r'%s/manage/episodeStatuses(/?)' % sickrage.app.config.web_root, EpisodeStatusesHandler),
            (r'%s/manage/changeEpisodeStatuses(/?)' % sickrage.app.config.web_root, ChangeEpisodeStatusesHandler),
            (r'%s/manage/setEpisodeStatus(/?)' % sickrage.app.config.web_root, SetEpisodeStatusHandler),
            (r'%s/manage/showSubtitleMissed(/?)' % sickrage.app.config.web_root, ShowSubtitleMissedHandler),
            (r'%s/manage/subtitleMissed(/?)' % sickrage.app.config.web_root, SubtitleMissedHandler),
            (r'%s/manage/downloadSubtitleMissed(/?)' % sickrage.app.config.web_root, DownloadSubtitleMissedHandler),
            (r'%s/manage/backlogShow(/?)' % sickrage.app.config.web_root, BacklogShowHandler),
            (r'%s/manage/backlogOverview(/?)' % sickrage.app.config.web_root, BacklogOverviewHandler),
            (r'%s/manage/massEdit(/?)' % sickrage.app.config.web_root, MassEditHandler),
            (r'%s/manage/massUpdate(/?)' % sickrage.app.config.web_root, MassUpdateHandler),
            (r'%s/manage/failedDownloads(/?)' % sickrage.app.config.web_root, FailedDownloadsHandler),
            (r'%s/manage/manageQueues(/?)' % sickrage.app.config.web_root, ManageQueuesHandler),
            (r'%s/manage/manageQueues/forceBacklogSearch(/?)' % sickrage.app.config.web_root, ForceBacklogSearchHandler),
            (r'%s/manage/manageQueues/forceDailySearch(/?)' % sickrage.app.config.web_root, ForceDailySearchHandler),
            (r'%s/manage/manageQueues/forceFindPropers(/?)' % sickrage.app.config.web_root, ForceFindPropersHandler),
            (r'%s/manage/manageQueues/pauseDailySearcher(/?)' % sickrage.app.config.web_root, PauseDailySearcherHandler),
            (r'%s/manage/manageQueues/pauseBacklogSearcher(/?)' % sickrage.app.config.web_root, PauseBacklogSearcherHandler),
            (r'%s/manage/manageQueues/pausePostProcessor(/?)' % sickrage.app.config.web_root, PausePostProcessorHandler),
            (r'%s/config(/?)' % sickrage.app.config.web_root, ConfigHandler),
            (r'%s/config/reset(/?)' % sickrage.app.config.web_root, ConfigResetHandler),
            (r'%s/config/anime(/?)' % sickrage.app.config.web_root, ConfigAnimeHandler),
            (r'%s/config/anime/saveAnime(/?)' % sickrage.app.config.web_root, ConfigSaveAnimeHandler),
            (r'%s/config/backuprestore(/?)' % sickrage.app.config.web_root, ConfigBackupRestoreHandler),
            (r'%s/config/backuprestore/backup(/?)' % sickrage.app.config.web_root, ConfigBackupHandler),
            (r'%s/config/backuprestore/restore(/?)' % sickrage.app.config.web_root, ConfigRestoreHandler),
            (r'%s/config/backuprestore/saveBackupRestore(/?)' % sickrage.app.config.web_root, SaveBackupRestoreHandler),
            (r'%s/config/general(/?)' % sickrage.app.config.web_root, ConfigGeneralHandler),
            (r'%s/config/general/generateApiKey(/?)' % sickrage.app.config.web_root, GenerateApiKeyHandler),
            (r'%s/config/general/saveRootDirs(/?)' % sickrage.app.config.web_root, SaveRootDirsHandler),
            (r'%s/config/general/saveAddShowDefaults(/?)' % sickrage.app.config.web_root, SaveAddShowDefaultsHandler),
            (r'%s/config/general/saveGeneral(/?)' % sickrage.app.config.web_root, SaveGeneralHandler),
            (r'%s/config/notifications(/?)' % sickrage.app.config.web_root, ConfigNotificationsHandler),
            (r'%s/config/notifications/saveNotifications(/?)' % sickrage.app.config.web_root, SaveNotificationsHandler),
            (r'%s/config/postProcessing(/?)' % sickrage.app.config.web_root, ConfigPostProcessingHandler),
            (r'%s/config/postProcessing/savePostProcessing(/?)' % sickrage.app.config.web_root, SavePostProcessingHandler),
            (r'%s/config/postProcessing/testNaming(/?)' % sickrage.app.config.web_root, TestNamingHandler),
            (r'%s/config/postProcessing/isNamingValid(/?)' % sickrage.app.config.web_root, IsNamingPatternValidHandler),
            (r'%s/config/postProcessing/isRarSupported(/?)' % sickrage.app.config.web_root, IsRarSupportedHandler),
            (r'%s/config/providers(/?)' % sickrage.app.config.web_root, ConfigProvidersHandler),
            (r'%s/config/providers/canAddNewznabProvider(/?)' % sickrage.app.config.web_root, CanAddNewznabProviderHandler),
            (r'%s/config/providers/canAddTorrentRssProvider(/?)' % sickrage.app.config.web_root, CanAddTorrentRssProviderHandler),
            (r'%s/config/providers/getNewznabCategories(/?)' % sickrage.app.config.web_root, GetNewznabCategoriesHandler),
            (r'%s/config/providers/saveProviders(/?)' % sickrage.app.config.web_root, SaveProvidersHandler),
            (r'%s/config/qualitySettings(/?)' % sickrage.app.config.web_root, ConfigQualitySettingsHandler),
            (r'%s/config/qualitySettings/saveQualities(/?)' % sickrage.app.config.web_root, SaveQualitiesHandler),
            (r'%s/config/search(/?)' % sickrage.app.config.web_root, ConfigSearchHandler),
            (r'%s/config/search/saveSearch(/?)' % sickrage.app.config.web_root, SaveSearchHandler),
            (r'%s/config/subtitles(/?)' % sickrage.app.config.web_root, ConfigSubtitlesHandler),
            (r'%s/config/subtitles/get_code(/?)' % sickrage.app.config.web_root, ConfigSubtitleGetCodeHandler),
            (r'%s/config/subtitles/wanted_languages(/?)' % sickrage.app.config.web_root, ConfigSubtitlesWantedLanguagesHandler),
            (r'%s/config/subtitles/saveSubtitles(/?)' % sickrage.app.config.web_root, SaveSubtitlesHandler),
        ])

        # HTTPS Cert/Key object
        ssl_ctx = None
        if sickrage.app.config.enable_https:
            ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
            ssl_ctx.load_cert_chain(sickrage.app.config.https_cert, sickrage.app.config.https_key)

        # Web Server
        self.server = HTTPServer(self.app, ssl_options=ssl_ctx, xheaders=sickrage.app.config.handle_reverse_proxy)

        try:
            self.server.listen(sickrage.app.config.web_port)
        except socket.error as e:
            sickrage.app.log.warning(e.strerror)
            raise SystemExit

        self.io_loop.start()

    def shutdown(self):
        if self.started:
            self.started = False
            if self.server:
                self.server.close_all_connections()
                self.server.stop()

            if self.io_loop:
                self.io_loop.stop()
コード例 #31
0
class WebServer(threading.Thread):
    def __init__(self, options={}, io_loop=None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.alive = True
        self.name = 'TORNADO'
        self.io_loop = io_loop or IOLoop.current()

        self.options = options
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', None)
        assert isinstance(self.options['port'], int)
        assert 'data_root' in self.options

        # web root
        self.options['web_root'] = ('/' + self.options['web_root'].lstrip('/')) if self.options[
            'web_root'] else ''

        # tornado setup
        self.enable_https = self.options['enable_https']
        self.https_cert = self.options['https_cert']
        self.https_key = self.options['https_key']

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert and os.path.exists(self.https_cert)) or not (
                self.https_key and os.path.exists(self.https_key)):
                if not create_https_certificates(self.https_cert, self.https_key):
                    logger.log(u'Unable to create CERT/KEY files, disabling HTTPS')
                    sickbeard.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (os.path.exists(self.https_cert) and os.path.exists(self.https_key)):
                logger.log(u'Disabled HTTPS because of missing CERT and KEY files', logger.WARNING)
                sickbeard.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application([],
                                 debug=True,
                                 autoreload=False,
                                 gzip=True,
                                 xheaders=sickbeard.HANDLE_REVERSE_PROXY,
                                 cookie_secret=sickbeard.COOKIE_SECRET,
                                 login_url='%s/login/' % self.options['web_root'],
        )

        # Main Handler
        self.app.add_handlers('.*$', [
            (r'%s/api/builder(/?)(.*)' % self.options['web_root'], webserve.ApiBuilder),
            (r'%s/api(/?.*)' % self.options['web_root'], webapi.Api),
            (r'%s/cache(/?.*)' % self.options['web_root'], webserve.Cache),
            (r'%s/config/general(/?.*)' % self.options['web_root'], webserve.ConfigGeneral),
            (r'%s/config/search(/?.*)' % self.options['web_root'], webserve.ConfigSearch),
            (r'%s/config/providers(/?.*)' % self.options['web_root'], webserve.ConfigProviders),
            (r'%s/config/subtitles(/?.*)' % self.options['web_root'], webserve.ConfigSubtitles),
            (r'%s/config/postProcessing(/?.*)' % self.options['web_root'], webserve.ConfigPostProcessing),
            (r'%s/config/notifications(/?.*)' % self.options['web_root'], webserve.ConfigNotifications),
            (r'%s/config/anime(/?.*)' % self.options['web_root'], webserve.ConfigAnime),
            (r'%s/config(/?.*)' % self.options['web_root'], webserve.Config),
            (r'%s/errorlogs(/?.*)' % self.options['web_root'], webserve.ErrorLogs),
            (r'%s/history(/?.*)' % self.options['web_root'], webserve.History),
            (r'%s/home/is_alive(/?.*)' % self.options['web_root'], webserve.IsAliveHandler),
            (r'%s/home/addShows(/?.*)' % self.options['web_root'], webserve.NewHomeAddShows),
            (r'%s/home/postprocess(/?.*)' % self.options['web_root'], webserve.HomePostProcess),
            (r'%s/home(/?.*)' % self.options['web_root'], webserve.Home),
            (r'%s/manage/manageSearches(/?.*)' % self.options['web_root'], webserve.ManageSearches),
            (r'%s/manage/showQueueOverview(/?.*)' % self.options['web_root'], webserve.showQueueOverview),
            (r'%s/manage/(/?.*)' % self.options['web_root'], webserve.Manage),
            (r'%s/ui(/?.*)' % self.options['web_root'], webserve.UI),
            (r'%s/browser(/?.*)' % self.options['web_root'], webserve.WebFileBrowser),
            (r'%s(/?.*)' % self.options['web_root'], webserve.MainHandler),
        ])

        # webui login/logout handlers
        self.app.add_handlers('.*$', [
            (r'%s/login(/?)' % self.options['web_root'], webserve.LoginHandler),
            (r'%s/logout(/?)' % self.options['web_root'], webserve.LogoutHandler),
        ])

        # Web calendar handler (Needed because option Unprotected calendar)
        self.app.add_handlers('.*$', [
            (r'%s/calendar' % self.options['web_root'], webserve.CalendarHandler),
        ])

        # Static File Handlers
        self.app.add_handlers('.*$', [
            # favicon
            (r'%s/(favicon\.ico)' % self.options['web_root'], StaticFileHandler,
             {'path': os.path.join(self.options['data_root'], 'images/ico/favicon.ico')}),

            # images
            (r'%s/images/(.*)' % self.options['web_root'], StaticFileHandler,
             {'path': os.path.join(self.options['data_root'], 'images')}),

            # cached images
            (r'%s/cache/images/(.*)' % self.options['web_root'], StaticFileHandler,
             {'path': os.path.join(sickbeard.CACHE_DIR, 'images')}),

            # css
            (r'%s/css/(.*)' % self.options['web_root'], StaticFileHandler,
             {'path': os.path.join(self.options['data_root'], 'css')}),

            # javascript
            (r'%s/js/(.*)' % self.options['web_root'], StaticFileHandler,
             {'path': os.path.join(self.options['data_root'], 'js')}),
        ])


    def run(self):
        if self.enable_https:
            protocol = 'https'
            self.server = HTTPServer(self.app, ssl_options={'certfile': self.https_cert, 'keyfile': self.https_key})
        else:
            protocol = 'http'
            self.server = HTTPServer(self.app)

        logger.log(u'Starting SickGear on ' + protocol + '://' + str(self.options['host']) + ':' + str(
            self.options['port']) + '/')

        try:
            self.server.listen(self.options['port'], self.options['host'])
        except:
            etype, evalue, etb = sys.exc_info()
            logger.log(
                'Could not start webserver on %s. Excpeption: %s, Error: %s' % (self.options['port'], etype, evalue),
                logger.ERROR)
            return

        try:
            self.io_loop.start()
            self.io_loop.close(True)
        except (IOError, ValueError):
            # Ignore errors like 'ValueError: I/O operation on closed kqueue fd'. These might be thrown during a reload.
            pass

    def shutDown(self):
        self.alive = False
        self.io_loop.stop()
コード例 #32
0
ファイル: webserveInit.py プロジェクト: mmazur519/SickRage
def initWebServer(options={}):
    options.setdefault('port', 8081)
    options.setdefault('host', '0.0.0.0')
    options.setdefault('log_dir', None)
    options.setdefault('username', '')
    options.setdefault('password', '')
    options.setdefault('web_root', '/')
    assert isinstance(options['port'], int)
    assert 'data_root' in options

    # tornado setup
    enable_https = options['enable_https']
    https_cert = options['https_cert']
    https_key = options['https_key']

    if enable_https:
        # If either the HTTPS certificate or key do not exist, make some self-signed ones.
        if 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.log(u"Unable to create CERT/KEY files, disabling HTTPS")
                sickbeard.ENABLE_HTTPS = False
                enable_https = False

        if not (os.path.exists(https_cert) and os.path.exists(https_key)):
            logger.log(u"Disabled HTTPS because of missing CERT and KEY files", logger.WARNING)
            sickbeard.ENABLE_HTTPS = False
            enable_https = False

    # Load the app
    app = Application([],
                        debug=False,
                        gzip=True,
                        xheaders=sickbeard.HANDLE_REVERSE_PROXY,
                        cookie_secret='61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo='
    )

    # Main Handler
    app.add_handlers(".*$", [
        (r"%s" % options['web_root'], RedirectHandler, {'url': '%s/home/' % options['web_root']}),
        (r'%s/api/(.*)(/?)' % options['web_root'], webapi.Api),
        (r'%s/(.*)(/?)' % options['web_root'], webserve.MainHandler)
    ])

    # Static Path Handler
    app.add_handlers(".*$", [
        (r'%s/(favicon\.ico)' % options['web_root'], MultiStaticFileHandler,
         {'paths': [os.path.join(options['data_root'], 'images/ico/favicon.ico')]}),
        (r'%s/%s/(.*)(/?)' % (options['web_root'], 'images'), MultiStaticFileHandler,
         {'paths': [os.path.join(options['data_root'], 'images'),
                    os.path.join(sickbeard.CACHE_DIR, 'images')]}),
        (r'%s/%s/(.*)(/?)' % (options['web_root'], 'css'), MultiStaticFileHandler,
         {'paths': [os.path.join(options['data_root'], 'css')]}),
        (r'%s/%s/(.*)(/?)' % (options['web_root'], 'js'), MultiStaticFileHandler,
         {'paths': [os.path.join(options['data_root'], 'js')]})

    ])

    global server

    if enable_https:
        protocol = "https"
        server = HTTPServer(app, no_keep_alive=True,
                            ssl_options={"certfile": https_cert, "keyfile": https_key})
    else:
        protocol = "http"
        server = HTTPServer(app, no_keep_alive=True)

    logger.log(u"Starting SickRage on " + protocol + "://" + str(options['host']) + ":" + str(
        options['port']) + "/")

    try:
        server.listen(options['port'], options['host'])
    except:
        pass
コード例 #33
0
def runCouchPotato(options, base_path, args, data_dir=None, log_dir=None, Env=None, desktop=None):

    try:
        locale.setlocale(locale.LC_ALL, "")
        encoding = locale.getpreferredencoding()
    except (locale.Error, IOError):
        encoding = None

    # for OSes that are poorly configured I'll just force UTF-8
    if not encoding or encoding in ("ANSI_X3.4-1968", "US-ASCII", "ASCII"):
        encoding = "UTF-8"

    Env.set("encoding", encoding)

    # Do db stuff
    db_path = sp(os.path.join(data_dir, "database"))
    old_db_path = os.path.join(data_dir, "couchpotato.db")

    # Remove database folder if both exists
    if os.path.isdir(db_path) and os.path.isfile(old_db_path):
        db = SuperThreadSafeDatabase(db_path)
        db.open()
        db.destroy()

    # Check if database exists
    db = SuperThreadSafeDatabase(db_path)
    db_exists = db.exists()
    if db_exists:

        # Backup before start and cleanup old backups
        backup_path = sp(os.path.join(data_dir, "db_backup"))
        backup_count = 5
        existing_backups = []
        if not os.path.isdir(backup_path):
            os.makedirs(backup_path)

        for root, dirs, files in os.walk(backup_path):
            # Only consider files being a direct child of the backup_path
            if root == backup_path:
                for backup_file in sorted(files):
                    ints = re.findall("\d+", backup_file)

                    # Delete non zip files
                    if len(ints) != 1:
                        try:
                            os.remove(os.path.join(root, backup_file))
                        except:
                            pass
                    else:
                        existing_backups.append((int(ints[0]), backup_file))
            else:
                # Delete stray directories.
                shutil.rmtree(root)

        # Remove all but the last 5
        for eb in existing_backups[:-backup_count]:
            os.remove(os.path.join(backup_path, eb[1]))

        # Create new backup
        new_backup = sp(os.path.join(backup_path, "%s.tar.gz" % int(time.time())))
        zipf = tarfile.open(new_backup, "w:gz")
        for root, dirs, files in os.walk(db_path):
            for zfilename in files:
                zipf.add(
                    os.path.join(root, zfilename),
                    arcname="database/%s" % os.path.join(root[len(db_path) + 1 :], zfilename),
                )
        zipf.close()

        # Open last
        db.open()

    else:
        db.create()

    # Force creation of cachedir
    log_dir = sp(log_dir)
    cache_dir = sp(os.path.join(data_dir, "cache"))
    python_cache = sp(os.path.join(cache_dir, "python"))

    if not os.path.exists(cache_dir):
        os.mkdir(cache_dir)
    if not os.path.exists(python_cache):
        os.mkdir(python_cache)

    session = requests.Session()
    session.max_redirects = 5

    # Register environment settings
    Env.set("app_dir", sp(base_path))
    Env.set("data_dir", sp(data_dir))
    Env.set("log_path", sp(os.path.join(log_dir, "CouchPotato.log")))
    Env.set("db", db)
    Env.set("http_opener", session)
    Env.set("cache_dir", cache_dir)
    Env.set("cache", FileSystemCache(python_cache))
    Env.set("console_log", options.console_log)
    Env.set("quiet", options.quiet)
    Env.set("desktop", desktop)
    Env.set("daemonized", options.daemon)
    Env.set("args", args)
    Env.set("options", options)

    # Determine debug
    debug = options.debug or Env.setting("debug", default=False, type="bool")
    Env.set("debug", debug)

    # Development
    development = Env.setting("development", default=False, type="bool")
    Env.set("dev", development)

    # Disable logging for some modules
    for logger_name in ["enzyme", "guessit", "subliminal", "apscheduler", "tornado", "requests"]:
        logging.getLogger(logger_name).setLevel(logging.ERROR)

    for logger_name in ["gntp"]:
        logging.getLogger(logger_name).setLevel(logging.WARNING)

    # Disable SSL warning
    disable_warnings()

    # Use reloader
    reloader = debug is True and development and not Env.get("desktop") and not options.daemon

    # Logger
    logger = logging.getLogger()
    formatter = logging.Formatter("%(asctime)s %(levelname)s %(message)s", "%m-%d %H:%M:%S")
    level = logging.DEBUG if debug else logging.INFO
    logger.setLevel(level)
    logging.addLevelName(19, "INFO")

    # To screen
    if (debug or options.console_log) and not options.quiet and not options.daemon:
        hdlr = logging.StreamHandler(sys.stderr)
        hdlr.setFormatter(formatter)
        logger.addHandler(hdlr)

    # To file
    hdlr2 = handlers.RotatingFileHandler(Env.get("log_path"), "a", 500000, 10, encoding=Env.get("encoding"))
    hdlr2.setFormatter(formatter)
    logger.addHandler(hdlr2)

    # Start logging & enable colors
    # noinspection PyUnresolvedReferences
    import color_logs
    from couchpotato.core.logger import CPLog

    log = CPLog(__name__)
    log.debug("Started with options %s", options)

    # Check soft-chroot dir exists:
    try:
        # Load Soft-Chroot
        soft_chroot = Env.get("softchroot")
        soft_chroot_dir = Env.setting("soft_chroot", section="core", default=None, type="unicode")
        soft_chroot.initialize(soft_chroot_dir)
    except SoftChrootInitError as exc:
        log.error(exc)
        return
    except:
        log.error("Unable to check whether SOFT-CHROOT is defined")
        return

    # Check available space
    try:
        total_space, available_space = getFreeSpace(data_dir)
        if available_space < 100:
            log.error(
                "Shutting down as CP needs some space to work. You'll get corrupted data otherwise. Only %sMB left",
                available_space,
            )
            return
    except:
        log.error("Failed getting diskspace: %s", traceback.format_exc())

    def customwarn(message, category, filename, lineno, file=None, line=None):
        log.warning("%s %s %s line:%s", (category, message, filename, lineno))

    warnings.showwarning = customwarn

    # Create app
    from couchpotato import WebHandler

    web_base = ("/" + Env.setting("url_base").lstrip("/") + "/") if Env.setting("url_base") else "/"
    Env.set("web_base", web_base)

    api_key = Env.setting("api_key")
    if not api_key:
        api_key = uuid4().hex
        Env.setting("api_key", value=api_key)

    api_base = r"%sapi/%s/" % (web_base, api_key)
    Env.set("api_base", api_base)

    # Basic config
    host = Env.setting("host", default="0.0.0.0")
    host6 = Env.setting("host6", default="::")

    config = {
        "use_reloader": reloader,
        "port": tryInt(Env.setting("port", default=5050)),
        "host": host if host and len(host) > 0 else "0.0.0.0",
        "host6": host6 if host6 and len(host6) > 0 else "::",
        "ssl_cert": Env.setting("ssl_cert", default=None),
        "ssl_key": Env.setting("ssl_key", default=None),
    }

    # Load the app
    application = Application(
        [],
        log_function=lambda x: None,
        debug=config["use_reloader"],
        gzip=True,
        cookie_secret=api_key,
        login_url="%slogin/" % web_base,
    )
    Env.set("app", application)

    # Request handlers
    application.add_handlers(
        ".*$",
        [
            (r"%snonblock/(.*)(/?)" % api_base, NonBlockHandler),
            # API handlers
            (r"%s(.*)(/?)" % api_base, ApiHandler),  # Main API handler
            (r"%sgetkey(/?)" % web_base, KeyHandler),  # Get API key
            (r"%s" % api_base, RedirectHandler, {"url": web_base + "docs/"}),  # API docs
            # Login handlers
            (r"%slogin(/?)" % web_base, LoginHandler),
            (r"%slogout(/?)" % web_base, LogoutHandler),
            # Catch all webhandlers
            (r"%s(.*)(/?)" % web_base, WebHandler),
            (r"(.*)", WebHandler),
        ],
    )

    # Static paths
    static_path = "%sstatic/" % web_base
    for dir_name in ["fonts", "images", "scripts", "style"]:
        application.add_handlers(
            ".*$",
            [
                (
                    "%s%s/(.*)" % (static_path, dir_name),
                    StaticFileHandler,
                    {"path": sp(os.path.join(base_path, "couchpotato", "static", dir_name))},
                )
            ],
        )
    Env.set("static_path", static_path)

    # Load configs & plugins
    loader = Env.get("loader")
    loader.preload(root=sp(base_path))
    loader.run()

    # Fill database with needed stuff
    fireEvent("database.setup")
    if not db_exists:
        fireEvent("app.initialize", in_order=True)
    fireEvent("app.migrate")

    # Go go go!
    from tornado.ioloop import IOLoop
    from tornado.autoreload import add_reload_hook

    loop = IOLoop.current()

    # Reload hook
    def reload_hook():
        fireEvent("app.shutdown")

    add_reload_hook(reload_hook)

    # Some logging and fire load event
    try:
        log.info("Starting server on port %(port)s", config)
    except:
        pass
    fireEventAsync("app.load")

    ssl_options = None
    if config["ssl_cert"] and config["ssl_key"]:
        ssl_options = {"certfile": config["ssl_cert"], "keyfile": config["ssl_key"]}

    server = HTTPServer(application, no_keep_alive=True, ssl_options=ssl_options)

    try_restart = True
    restart_tries = 5

    while try_restart:
        try:
            if config["host"].startswith("unix:"):
                server.add_socket(bind_unix_socket(config["host"][5:]))
            else:
                server.listen(config["port"], config["host"])

                if Env.setting("ipv6", default=False):
                    try:
                        server.listen(config["port"], config["host6"])
                    except:
                        log.info2("Tried to bind to IPV6 but failed")

            loop.start()
            server.close_all_connections()
            server.stop()
            loop.close(all_fds=True)
        except Exception as e:
            log.error("Failed starting: %s", traceback.format_exc())
            try:
                nr, msg = e
                if nr == 48:
                    log.info(
                        "Port (%s) needed for CouchPotato is already in use, try %s more time after few seconds",
                        (config.get("port"), restart_tries),
                    )
                    time.sleep(1)
                    restart_tries -= 1

                    if restart_tries > 0:
                        continue
                    else:
                        return
            except ValueError:
                return
            except:
                pass

            raise

        try_restart = False
コード例 #34
0
def initWebServer(options={}):
    options.setdefault('port', 8081)
    options.setdefault('host', '0.0.0.0')
    options.setdefault('log_dir', None)
    options.setdefault('username', '')
    options.setdefault('password', '')
    options.setdefault('web_root', '/')
    assert isinstance(options['port'], int)
    assert 'data_root' in options

    # tornado setup
    enable_https = options['enable_https']
    https_cert = options['https_cert']
    https_key = options['https_key']

    if enable_https:
        # If either the HTTPS certificate or key do not exist, make some self-signed ones.
        if 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.log(u"Unable to create CERT/KEY files, disabling HTTPS")
                sickbeard.ENABLE_HTTPS = False
                enable_https = False

        if not (os.path.exists(https_cert) and os.path.exists(https_key)):
            logger.log(u"Disabled HTTPS because of missing CERT and KEY files", logger.WARNING)
            sickbeard.ENABLE_HTTPS = False
            enable_https = False

    # Load the app
    app = Application([],
                        debug=False,
                        gzip=True,
                        xheaders=sickbeard.HANDLE_REVERSE_PROXY,
                        cookie_secret='61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo='
    )

    # Main Handler
    app.add_handlers(".*$", [
        (r"/", RedirectHandler, {'url': '%s/home/' % options['web_root']}),
        (r'%s/api/(.*)(/?)' % options['web_root'], webapi.Api),
        (r'%s/(.*)(/?)' % options['web_root'], webserve.IndexHandler)
    ])

    # Static Path Handler
    app.add_handlers(".*$", [
        (r'%s/(favicon\.ico)' % options['web_root'], MultiStaticFileHandler,
         {'paths': [os.path.join(options['data_root'], 'images/ico/favicon.ico')]}),
        (r'%s/%s/(.*)(/?)' % (options['web_root'], 'images'), MultiStaticFileHandler,
         {'paths': [os.path.join(options['data_root'], 'images'),
                    os.path.join(sickbeard.CACHE_DIR, 'images')]}),
        (r'%s/%s/(.*)(/?)' % (options['web_root'], 'css'), MultiStaticFileHandler,
         {'paths': [os.path.join(options['data_root'], 'css')]}),
        (r'%s/%s/(.*)(/?)' % (options['web_root'], 'js'), MultiStaticFileHandler,
         {'paths': [os.path.join(options['data_root'], 'js')]})

    ])

    global server

    if enable_https:
        protocol = "https"
        server = HTTPServer(app, no_keep_alive=True,
                            ssl_options={"certfile": https_cert, "keyfile": https_key})
    else:
        protocol = "http"
        server = HTTPServer(app, no_keep_alive=True)

    logger.log(u"Starting SickRage on " + protocol + "://" + str(options['host']) + ":" + str(
        options['port']) + "/")

    try:
        server.listen(options['port'], options['host'])
    except:
        pass
コード例 #35
0
ファイル: core.py プロジェクト: warrmr/Medusa
class AppWebServer(threading.Thread):
    def __init__(self, options=None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.alive = True
        self.name = 'TORNADO'

        self.options = options or {}
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', '/')
        assert isinstance(self.options['port'], int)
        assert 'data_root' in self.options

        self.server = None
        self.io_loop = None

        # video root
        if app.ROOT_DIRS:
            root_dirs = app.ROOT_DIRS
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if self.options['web_root']:
            app.WEB_ROOT = self.options['web_root'] = clean_url_path(
                self.options['web_root'])

        # Configure root to selected theme.
        app.WEB_ROOT = self.options['theme_path'] = clean_url_path(
            app.WEB_ROOT)

        # Configure the directory to the theme's data root.
        app.THEME_DATA_ROOT = self.options['theme_data_root'] = os.path.join(
            self.options['data_root'], app.THEME_NAME)

        # api root
        if not app.API_KEY:
            app.API_KEY = generate_api_key()
        self.options['api_root'] = r'{root}/api/(?:v1/)?{key}'.format(
            root=app.WEB_ROOT, key=app.API_KEY)
        self.options['api_v2_root'] = r'{root}/api/v2'.format(
            root=app.WEB_ROOT)

        # websocket root
        self.options['web_socket'] = r'{root}/ws'.format(root=app.WEB_ROOT)

        # tornado setup
        self.enable_https = self.options['enable_https']
        self.https_cert = self.options['https_cert']
        self.https_key = self.options['https_key']

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert
                    and os.path.exists(self.https_cert)) or not (
                        self.https_key and os.path.exists(self.https_key)):
                if not create_https_certificates(self.https_cert,
                                                 self.https_key):
                    log.info(
                        'Unable to create CERT/KEY files, disabling HTTPS')
                    app.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (os.path.exists(self.https_cert)
                    and os.path.exists(self.https_key)):
                log.warning(
                    'Disabled HTTPS because of missing CERT and KEY files')
                app.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application(
            [],
            debug=True,
            autoreload=False,
            gzip=app.WEB_USE_GZIP,
            xheaders=app.HANDLE_REVERSE_PROXY,
            cookie_secret=app.WEB_COOKIE_SECRET,
            login_url=r'{root}/login/'.format(root=self.options['theme_path']),
            log_function=self.log_request,
        )

        self.app.add_handlers('.*$',
                              get_apiv2_handlers(self.options['api_v2_root']))

        # Websocket handler
        self.app.add_handlers('.*$', [(r'{base}/ui(/?.*)'.format(
            base=self.options['web_socket']), WebSocketUIHandler)])

        # Static File Handlers
        self.app.add_handlers(
            '.*$',
            [
                # favicon
                (r'{base}/favicon\.ico()'.format(
                    base=self.options['theme_path']), StaticFileHandler, {
                        'path':
                        os.path.join(self.options['theme_data_root'], 'assets',
                                     'img', 'ico', 'favicon.ico')
                    }),

                # images
                (r'{base}/images/(.*)'.format(base=self.options['theme_path']),
                 StaticFileHandler, {
                     'path':
                     os.path.join(self.options['theme_data_root'], 'assets',
                                  'img')
                 }),

                # cached images
                (r'{base}/cache/images/(.*)'.format(
                    base=self.options['theme_path']), StaticFileHandler, {
                        'path': os.path.join(app.CACHE_DIR, 'images')
                    }),

                # css
                (r'{base}/css/(.*)'.format(base=self.options['theme_path']),
                 StaticFileHandler, {
                     'path':
                     os.path.join(self.options['theme_data_root'], 'assets',
                                  'css')
                 }),

                # javascript
                (r'{base}/js/(.*)'.format(base=self.options['theme_path']),
                 StaticFileHandler, {
                     'path':
                     os.path.join(self.options['theme_data_root'], 'assets',
                                  'js')
                 }),

                # fonts
                (r'{base}/fonts/(.*)'.format(base=self.options['theme_path']),
                 StaticFileHandler, {
                     'path':
                     os.path.join(self.options['theme_data_root'], 'assets',
                                  'fonts')
                 }),

                # videos
                (r'{base}/videos/(.*)'.format(base=self.options['theme_path']),
                 StaticFileHandler, {
                     'path': self.video_root
                 }),

                # vue dist
                (r'{base}/vue/dist/(.*)'.format(
                    base=self.options['theme_path']), StaticFileHandler, {
                        'path': os.path.join(self.options['theme_data_root'],
                                             'vue')
                    }),

                # vue index.html
                (r'{base}/vue/?.*()'.format(base=self.options['theme_path']),
                 AuthenticatedStaticFileHandler, {
                     'path':
                     os.path.join(self.options['theme_data_root'],
                                  'index.html'),
                     'default_filename':
                     'index.html'
                 }),
            ])

        # Used for hot-swapping themes
        # This is the 2nd rule from the end, because the last one is always `self.app.wildcard_router`
        self.app.static_file_handlers = self.app.default_router.rules[-2]

        # API v1 handlers
        self.app.add_handlers(
            '.*$',
            [
                # Main handler
                (r'{base}(/?.*)'.format(base=self.options['api_root']),
                 ApiHandler),

                # Key retrieval
                (r'{base}/getkey(/?.*)'.format(base=self.options['web_root']),
                 KeyHandler),

                # Builder redirect
                (r'{base}/api/builder'.format(base=self.options['web_root']),
                 RedirectHandler, {
                     'url':
                     '{base}/apibuilder/'.format(base=self.options['web_root'])
                 }),

                # Webui login/logout handlers
                (r'{base}/login(/?)'.format(base=self.options['theme_path']),
                 LoginHandler),
                (r'{base}/logout(/?)'.format(base=self.options['theme_path']),
                 LogoutHandler),
                (r'{base}/token(/?)'.format(base=self.options['web_root']),
                 TokenHandler),

                # Web calendar handler (Needed because option Unprotected calendar)
                (r'{base}/calendar'.format(base=self.options['web_root']),
                 CalendarHandler),

                # webui handlers
            ] + self._get_webui_routes())

    def _get_webui_routes(self):
        webroot = self.options['theme_path']
        route._routes = list(
            reversed([
                url(webroot + u.regex.pattern, u.handler_class, u.kwargs,
                    u.name) for u in route.get_routes()
            ]))
        return route.get_routes()

    def run(self):
        # Start event loop in python3
        if six.PY3:
            import asyncio
            asyncio.set_event_loop(asyncio.new_event_loop())

        if self.enable_https:
            protocol = 'https'
            self.server = HTTPServer(self.app,
                                     ssl_options={
                                         'certfile': self.https_cert,
                                         'keyfile': self.https_key
                                     })
        else:
            protocol = 'http'
            self.server = HTTPServer(self.app)

        log.info(
            'Starting Medusa on {scheme}://{host}:{port}{web_root}/', {
                'scheme': protocol,
                'host': self.options['host'],
                'port': self.options['port'],
                'web_root': self.options['theme_path']
            })

        try:
            self.server.listen(self.options['port'], self.options['host'])
        except Exception as ex:
            if app.LAUNCH_BROWSER and not self.daemon:
                app.instance.launch_browser(
                    'https' if app.ENABLE_HTTPS else 'http',
                    self.options['port'], app.WEB_ROOT)
                log.info('Launching browser and exiting')
            log.info(
                'Could not start the web server on port {port}. Exception: {ex}',
                {
                    'port': self.options['port'],
                    'ex': ex
                })
            os._exit(1)  # pylint: disable=protected-access

        try:
            self.io_loop = IOLoop.current()
            self.io_loop.start()
        except (IOError, ValueError):
            # Ignore errors like 'ValueError: I/O operation on closed kqueue fd'. These might be thrown during a reload.
            pass

    def shutDown(self):
        self.alive = False
        self.io_loop.stop()

    def log_request(self, handler):
        """
        Write a completed HTTP request to the logs.

        This method handles logging Tornado requests.
        """
        if not app.WEB_LOG:
            return

        level = None
        if handler.get_status() < 400:
            level = logging.INFO
        elif handler.get_status() < 500:
            # Don't log normal APIv2 RESTful responses as warnings
            if isinstance(handler, BaseRequestHandler):
                level = logging.INFO
            else:
                level = logging.WARNING
        else:
            # If a real exception was raised in APIv2,
            # let `BaseRequestHandler.log_exception` handle the logging
            if not isinstance(handler, BaseRequestHandler):
                level = logging.ERROR

        if level is None:
            return

        log.log(
            level, '{status} {summary} {time:.2f}ms', {
                'status': handler.get_status(),
                'summary': handler._request_summary(),
                'time': 1000.0 * handler.request.request_time()
            })
コード例 #36
0
ファイル: webserveInit.py プロジェクト: Halibutt/SickRage
class SRWebServer(threading.Thread):
    def __init__(self, options={}, io_loop=None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.alive = True
        self.name = "TORNADO"
        self.io_loop = io_loop or IOLoop.current()

        self.options = options
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', None)
        assert isinstance(self.options['port'], int)
        assert 'data_root' in self.options

        # video root
        if sickbeard.ROOT_DIRS:
            root_dirs = sickbeard.ROOT_DIRS.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        self.options['web_root'] = ('/' + self.options['web_root'].lstrip('/')) if self.options[
            'web_root'] else ''

        # tornado setup
        self.enable_https = self.options['enable_https']
        self.https_cert = self.options['https_cert']
        self.https_key = self.options['https_key']

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert and os.path.exists(self.https_cert)) or not (
                self.https_key and os.path.exists(self.https_key)):
                if not create_https_certificates(self.https_cert, self.https_key):
                    logger.log(u"Unable to create CERT/KEY files, disabling HTTPS")
                    sickbeard.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (os.path.exists(self.https_cert) and os.path.exists(self.https_key)):
                logger.log(u"Disabled HTTPS because of missing CERT and KEY files", logger.WARNING)
                sickbeard.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application([],
                                 debug=True,
                                 autoreload=False,
                                 gzip=True,
                                 xheaders=sickbeard.HANDLE_REVERSE_PROXY,
                                 cookie_secret='61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo='
        )

        # Main Handler
        self.app.add_handlers(".*$", [
            (r'%s/api/(.*)(/?)' % self.options['web_root'], webapi.Api),
            (r'%s/(.*)(/?)' % self.options['web_root'], webserve.MainHandler),
            (r'(.*)', webserve.MainHandler)
        ])

        # Static Path Handler
        self.app.add_handlers(".*$", [
            (r'%s/(favicon\.ico)' % self.options['web_root'], MultiStaticFileHandler,
             {'paths': [os.path.join(self.options['data_root'], 'images/ico/favicon.ico')]}),
            (r'%s/%s/(.*)(/?)' % (self.options['web_root'], 'images'), MultiStaticFileHandler,
             {'paths': [os.path.join(self.options['data_root'], 'images'),
                        os.path.join(sickbeard.CACHE_DIR, 'images')]}),
            (r'%s/%s/(.*)(/?)' % (self.options['web_root'], 'css'), MultiStaticFileHandler,
             {'paths': [os.path.join(self.options['data_root'], 'css')]}),
            (r'%s/%s/(.*)(/?)' % (self.options['web_root'], 'js'), MultiStaticFileHandler,
             {'paths': [os.path.join(self.options['data_root'], 'js')]}),
        ])

        # Static Videos Path
        if self.video_root:
            self.app.add_handlers(".*$", [
                (r'%s/%s/(.*)' % (self.options['web_root'], 'videos'), MultiStaticFileHandler,
                 {'paths': [self.video_root]}),
            ])

    def run(self):
        if self.enable_https:
            protocol = "https"
            self.server = HTTPServer(self.app, no_keep_alive=True,
                                     ssl_options={"certfile": self.https_cert, "keyfile": self.https_key})
        else:
            protocol = "http"
            self.server = HTTPServer(self.app, no_keep_alive=True)

        logger.log(u"Starting SickRage on " + protocol + "://" + str(self.options['host']) + ":" + str(
            self.options['port']) + "/")

        try:
            self.server.listen(self.options['port'], self.options['host'])
        except:
            etype, evalue, etb = sys.exc_info()
            logger.log(
                "Could not start webserver on %s. Excpeption: %s, Error: %s" % (self.options['port'], etype, evalue),
                logger.ERROR)
            return

        try:
            self.io_loop.start()
            self.io_loop.close(True)
        except (IOError, ValueError):
            # Ignore errors like "ValueError: I/O operation on closed kqueue fd". These might be thrown during a reload.
            pass

    def shutDown(self):
        self.alive = False
        if self.server:
            logger.log("Shutting down tornado")
            self.server.stop()
            self.io_loop.stop()
            self.join()
コード例 #37
0
ファイル: webserveInit.py プロジェクト: Hellowlol/SickRage
class SRWebServer(threading.Thread):
    def __init__(self, options={}, io_loop=None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.alive = True
        self.name = "TORNADO"
        self.io_loop = io_loop or IOLoop.current()

        self.options = options
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', '/')
        assert isinstance(self.options['port'], int)
        assert 'data_root' in self.options

        # video root
        if sickbeard.ROOT_DIRS:
            root_dirs = sickbeard.ROOT_DIRS.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if self.options['web_root']:
            sickbeard.WEB_ROOT = self.options['web_root'] = ('/' + self.options['web_root'].lstrip('/').strip('/'))

        # api root
        if not sickbeard.API_KEY:
            sickbeard.API_KEY = generateApiKey()
        self.options['api_root'] = r'%s/api/%s' % (sickbeard.WEB_ROOT, sickbeard.API_KEY)

        # tornado setup
        self.enable_https = self.options['enable_https']
        self.https_cert = self.options['https_cert']
        self.https_key = self.options['https_key']

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert and os.path.exists(self.https_cert)) or not (
                        self.https_key and os.path.exists(self.https_key)):
                if not create_https_certificates(self.https_cert, self.https_key):
                    logger.log(u"Unable to create CERT/KEY files, disabling HTTPS")
                    sickbeard.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (os.path.exists(self.https_cert) and os.path.exists(self.https_key)):
                logger.log(u"Disabled HTTPS because of missing CERT and KEY files", logger.WARNING)
                sickbeard.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application([],
                                 debug=True,
                                 autoreload=False,
                                 gzip=True,
                                 xheaders=sickbeard.HANDLE_REVERSE_PROXY,
                                 cookie_secret='61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=',
                                 login_url='%s/login/' % self.options['web_root'],
        )

        # Main Handlers
        self.app.add_handlers('.*$', [
            # webapi handler
            (r'%s(/?.*)' % self.options['api_root'], ApiHandler),

            # webapi key retrieval
            (r'%s/getkey(/?.*)' % self.options['web_root'], KeyHandler),

            # webapi builder redirect
            (r'%s/api/builder' % self.options['web_root'], RedirectHandler, {"url": self.options['web_root'] + '/apibuilder/'}),

            # webui login/logout handlers
            (r'%s/login(/?)' % self.options['web_root'], LoginHandler),
            (r'%s/logout(/?)' % self.options['web_root'], LogoutHandler),

            # webui handlers
        ] + route.get_routes(self.options['web_root']))

        # Static File Handlers
        self.app.add_handlers(".*$", [
            # favicon
            (r'%s/(favicon\.ico)' % self.options['web_root'], StaticFileHandler,
             {"path": os.path.join(self.options['data_root'], 'images/ico/favicon.ico')}),

            # images
            (r'%s/images/(.*)' % self.options['web_root'], StaticFileHandler,
             {"path": os.path.join(self.options['data_root'], 'images')}),

            # cached images
            (r'%s/cache/images/(.*)' % self.options['web_root'], StaticFileHandler,
             {"path": os.path.join(sickbeard.CACHE_DIR, 'images')}),

            # css
            (r'%s/css/(.*)' % self.options['web_root'], StaticFileHandler,
             {"path": os.path.join(self.options['data_root'], 'css')}),

            # javascript
            (r'%s/js/(.*)' % self.options['web_root'], StaticFileHandler,
             {"path": os.path.join(self.options['data_root'], 'js')}),

            # videos
        ] + [(r'%s/videos/(.*)' % self.options['web_root'], StaticFileHandler,
              {"path": self.video_root})])

    def run(self):
        if self.enable_https:
            protocol = "https"
            self.server = HTTPServer(self.app, ssl_options={"certfile": self.https_cert, "keyfile": self.https_key})
        else:
            protocol = "http"
            self.server = HTTPServer(self.app)

        logger.log(u"Starting SickRage on " + protocol + "://" + str(self.options['host']) + ":" + str(
            self.options['port']) + "/")

        try:
            self.server.listen(self.options['port'], self.options['host'])
        except:
            etype, evalue, etb = sys.exc_info()
            logger.log(
                "Could not start webserver on %s. Excpeption: %s, Error: %s" % (self.options['port'], etype, evalue),
                logger.ERROR)
            return

        try:
            self.io_loop.start()
            self.io_loop.close(True)
        except (IOError, ValueError):
            # Ignore errors like "ValueError: I/O operation on closed kqueue fd". These might be thrown during a reload.
            pass

    def shutDown(self):
        self.alive = False
        self.io_loop.stop()
コード例 #38
0
ファイル: __init__.py プロジェクト: eviljones/SiCKRAGE
class srWebServer(object):
    def __init__(self):
        self.started = False

    def start(self):
        self.started = True

        # video root
        self.video_root = None
        if sickrage.srCore.srConfig.ROOT_DIRS:
            root_dirs = sickrage.srCore.srConfig.ROOT_DIRS.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]

        # web root
        if sickrage.srCore.srConfig.WEB_ROOT:
            sickrage.srCore.srConfig.WEB_ROOT = sickrage.srCore.srConfig.WEB_ROOT = (
                '/' + sickrage.srCore.srConfig.WEB_ROOT.lstrip('/').strip('/'))

        # api root
        if not sickrage.srCore.srConfig.API_KEY:
            sickrage.srCore.srConfig.API_KEY = generateApiKey()
        self.api_root = r'%s/api/%s' % (sickrage.srCore.srConfig.WEB_ROOT,
                                        sickrage.srCore.srConfig.API_KEY)

        # tornado setup
        if sickrage.srCore.srConfig.ENABLE_HTTPS:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (sickrage.srCore.srConfig.HTTPS_CERT and os.path.exists(
                    sickrage.srCore.srConfig.HTTPS_CERT)) or not (
                        sickrage.srCore.srConfig.HTTPS_KEY and os.path.exists(
                            sickrage.srCore.srConfig.HTTPS_KEY)):
                if not create_https_certificates(
                        sickrage.srCore.srConfig.HTTPS_CERT,
                        sickrage.srCore.srConfig.HTTPS_KEY):
                    sickrage.srCore.srLogger.info(
                        "Unable to create CERT/KEY files, disabling HTTPS")
                    sickrage.srCore.srConfig.ENABLE_HTTPS = False

            if not (os.path.exists(sickrage.srCore.srConfig.HTTPS_CERT)
                    and os.path.exists(sickrage.srCore.srConfig.HTTPS_KEY)):
                sickrage.srCore.srLogger.warning(
                    "Disabled HTTPS because of missing CERT and KEY files")
                sickrage.srCore.srConfig.ENABLE_HTTPS = False

        # Load the app
        self.app = Application(
            [],
            debug=False,
            autoreload=False,
            gzip=sickrage.srCore.srConfig.WEB_USE_GZIP,
            xheaders=sickrage.srCore.srConfig.HANDLE_REVERSE_PROXY,
            cookie_secret=sickrage.srCore.srConfig.WEB_COOKIE_SECRET,
            login_url='%s/login/' % sickrage.srCore.srConfig.WEB_ROOT)

        # Main Handlers
        self.app.add_handlers(
            '.*$',
            [
                # webapi handler
                (r'%s(/?.*)' % self.api_root, ApiHandler),

                # webapi key retrieval
                (r'%s/getkey(/?.*)' % sickrage.srCore.srConfig.WEB_ROOT,
                 KeyHandler),

                # webapi builder redirect
                (r'%s/api/builder' % sickrage.srCore.srConfig.WEB_ROOT,
                 RedirectHandler, {
                     "url": sickrage.srCore.srConfig.WEB_ROOT + '/apibuilder/'
                 }),

                # webui login/logout handlers
                (r'%s/login(/?)' % sickrage.srCore.srConfig.WEB_ROOT,
                 LoginHandler),
                (r'%s/logout(/?)' % sickrage.srCore.srConfig.WEB_ROOT,
                 LogoutHandler),

                # webui handlers
            ] + Route.get_routes(sickrage.srCore.srConfig.WEB_ROOT))

        # Web calendar handler (Needed because option Unprotected calendar)
        self.app.add_handlers('.*$', [
            (r'%s/calendar' % sickrage.srCore.srConfig.WEB_ROOT,
             CalendarHandler),
        ])

        # Static File Handlers
        self.app.add_handlers(
            ".*$",
            [
                # favicon
                (r'%s/(favicon\.ico)' % sickrage.srCore.srConfig.WEB_ROOT,
                 StaticFileHandler, {
                     "path":
                     os.path.join(sickrage.srCore.srConfig.GUI_DIR,
                                  'images/ico/favicon.ico')
                 }),

                # images
                (r'%s.*?/images/(.*)' % sickrage.srCore.srConfig.WEB_ROOT,
                 StaticImageHandler, {
                     "path":
                     os.path.join(sickrage.srCore.srConfig.GUI_DIR, 'images')
                 }),

                # css
                (r'%s/css/(.*)' % sickrage.srCore.srConfig.WEB_ROOT,
                 StaticFileHandler, {
                     "path": os.path.join(sickrage.srCore.srConfig.GUI_DIR,
                                          'css')
                 }),

                # scss
                (r'%s/scss/(.*)' % sickrage.srCore.srConfig.WEB_ROOT,
                 StaticFileHandler, {
                     "path": os.path.join(sickrage.srCore.srConfig.GUI_DIR,
                                          'scss')
                 }),

                # fonts
                (r'%s/fonts/(.*)' % sickrage.srCore.srConfig.WEB_ROOT,
                 StaticFileHandler, {
                     "path":
                     os.path.join(sickrage.srCore.srConfig.GUI_DIR, 'fonts')
                 }),

                # javascript
                (r'%s/js/(.*)' % sickrage.srCore.srConfig.WEB_ROOT,
                 StaticFileHandler, {
                     "path": os.path.join(sickrage.srCore.srConfig.GUI_DIR,
                                          'js')
                 }),

                # videos
            ] + [(r'%s/videos/(.*)' % sickrage.srCore.srConfig.WEB_ROOT,
                  StaticFileHandler, {
                      "path": self.video_root
                  })])

        self.server = HTTPServer(self.app, no_keep_alive=True)

        if sickrage.srCore.srConfig.ENABLE_HTTPS:
            self.server.ssl_options = {
                "certfile": sickrage.srCore.srConfig.HTTPS_CERT,
                "keyfile": sickrage.srCore.srConfig.HTTPS_KEY
            }

        try:
            self.server.listen(sickrage.srCore.srConfig.WEB_PORT, None)
        except socket.error as e:
            print(e.message)
            raise

        # launch browser window
        if all(
            [not sickrage.NOLAUNCH, sickrage.srCore.srConfig.LAUNCH_BROWSER]):
            threading.Thread(
                None, lambda: launch_browser(
                    ('http', 'https')[sickrage.srCore.srConfig.ENABLE_HTTPS],
                    get_lan_ip(), sickrage.srCore.srConfig.WEB_PORT)).start()

        # clear mako cache folder
        makocache = os.path.join(sickrage.srCore.srConfig.CACHE_DIR, 'mako')
        if os.path.isdir(makocache):
            shutil.rmtree(makocache)

        sickrage.srCore.srLogger.info("SiCKRAGE :: STARTED")
        sickrage.srCore.srLogger.info("SiCKRAGE :: VERSION:[{}]".format(
            sickrage.srCore.VERSIONUPDATER.updater.version))
        sickrage.srCore.srLogger.info("SiCKRAGE :: CONFIG:[{}]".format(
            sickrage.CONFIG_FILE))
        sickrage.srCore.srLogger.info("SiCKRAGE :: URL:[{}://{}:{}/]".format(
            ('http', 'https')[sickrage.srCore.srConfig.ENABLE_HTTPS],
            get_lan_ip(), sickrage.srCore.srConfig.WEB_PORT))

    def shutdown(self):
        if self.started:
            self.server.close_all_connections()
            self.server.stop()
            self.started = False
コード例 #39
0
ファイル: __init__.py プロジェクト: SiCKRAGETV/SiCKRAGE
class WebServer(object):
    def __init__(self):
        super(WebServer, self).__init__()
        self.name = "TORNADO"
        self.daemon = True
        self.started = False
        self.video_root = None
        self.api_root = None
        self.app = None
        self.server = None

    def start(self):
        self.started = True

        # load languages
        tornado.locale.load_gettext_translations(sickrage.LOCALE_DIR, 'messages')

        # clear mako cache folder
        mako_cache = os.path.join(sickrage.app.cache_dir, 'mako')
        if os.path.isdir(mako_cache):
            shutil.rmtree(mako_cache)

        # video root
        if sickrage.app.config.root_dirs:
            root_dirs = sickrage.app.config.root_dirs.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]

        # web root
        if sickrage.app.config.web_root:
            sickrage.app.config.web_root = sickrage.app.config.web_root = (
                    '/' + sickrage.app.config.web_root.lstrip('/').strip('/'))

        # api root
        self.api_root = r'%s/api/%s' % (sickrage.app.config.web_root, sickrage.app.config.api_key)

        # tornado setup
        if sickrage.app.config.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (
                    sickrage.app.config.https_cert and os.path.exists(
                sickrage.app.config.https_cert)) or not (
                    sickrage.app.config.https_key and os.path.exists(sickrage.app.config.https_key)):
                if not create_https_certificates(sickrage.app.config.https_cert,
                                                 sickrage.app.config.https_key):
                    sickrage.app.log.info("Unable to create CERT/KEY files, disabling HTTPS")
                    sickrage.app.config.enable_https = False

            if not (os.path.exists(sickrage.app.config.https_cert) and os.path.exists(
                    sickrage.app.config.https_key)):
                sickrage.app.log.warning("Disabled HTTPS because of missing CERT and KEY files")
                sickrage.app.config.enable_https = False

        # Load the app
        self.app = Application(
            debug=True,
            autoreload=False,
            gzip=sickrage.app.config.web_use_gzip,
            cookie_secret=sickrage.app.config.web_cookie_secret,
            login_url='%s/login/' % sickrage.app.config.web_root)

        # Websocket handler
        self.app.add_handlers(".*$", [
            (r'%s/ws/ui' % sickrage.app.config.web_root, WebSocketUIHandler)
        ])

        # Static File Handlers
        self.app.add_handlers('.*$', [
            # api
            (r'%s/api/(\w{32})(/?.*)' % sickrage.app.config.web_root, ApiHandler),

            # redirect to home
            (r"(%s)" % sickrage.app.config.web_root, RedirectHandler,
             {"url": "%s/home" % sickrage.app.config.web_root}),

            # api builder
            (r'%s/api/builder' % sickrage.app.config.web_root, RedirectHandler,
             {"url": sickrage.app.config.web_root + '/apibuilder/'}),

            # login
            (r'%s/login(/?)' % sickrage.app.config.web_root, LoginHandler),

            # logout
            (r'%s/logout(/?)' % sickrage.app.config.web_root, LogoutHandler),

            # calendar
            (r'%s/calendar' % sickrage.app.config.web_root, CalendarHandler),

            # favicon
            (r'%s/(favicon\.ico)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'images/favicon.ico')}),

            # images
            (r'%s/images/(.*)' % sickrage.app.config.web_root, StaticImageHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'images')}),

            # css
            (r'%s/css/(.*)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'css')}),

            # scss
            (r'%s/scss/(.*)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'scss')}),

            # fonts
            (r'%s/fonts/(.*)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'fonts')}),

            # javascript
            (r'%s/js/(.*)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": os.path.join(sickrage.app.config.gui_static_dir, 'js')}),

            # videos
            (r'%s/videos/(.*)' % sickrage.app.config.web_root, StaticNoCacheFileHandler,
             {"path": self.video_root}),
        ])

        # Web Handlers
        self.app.add_handlers('.*$', Route.get_routes(sickrage.app.config.web_root))

        # HTTPS Cert/Key object
        ssl_ctx = None
        if sickrage.app.config.enable_https:
            ssl_ctx = ssl.create_default_context(ssl.Purpose.CLIENT_AUTH)
            ssl_ctx.load_cert_chain(sickrage.app.config.https_cert, sickrage.app.config.https_key)

        # Web Server
        self.server = HTTPServer(self.app, ssl_options=ssl_ctx, xheaders=sickrage.app.config.handle_reverse_proxy)

        try:
            self.server.listen(sickrage.app.config.web_port)

            sickrage.app.log.info(
                "SiCKRAGE :: STARTED")
            sickrage.app.log.info(
                "SiCKRAGE :: VERSION:[{}]".format(sickrage.version()))
            sickrage.app.log.info(
                "SiCKRAGE :: CONFIG:[{}] [v{}]".format(sickrage.app.config_file, sickrage.app.config.config_version))
            sickrage.app.log.info(
                "SiCKRAGE :: DATABASE:[v{}]".format(sickrage.app.main_db.version))
            sickrage.app.log.info(
                "SiCKRAGE :: URL:[{}://{}:{}{}]".format(('http', 'https')[sickrage.app.config.enable_https],
                                                        sickrage.app.config.web_host, sickrage.app.config.web_port,
                                                        sickrage.app.config.web_root))
        except socket.error as e:
            sickrage.app.log.warning(e.strerror)
            raise SystemExit

    def shutdown(self):
        if self.started:
            self.started = False
            if self.server:
                self.server.close_all_connections()
                self.server.stop()
コード例 #40
0
ファイル: httpd.py プロジェクト: adkinsjd/compactor
class HTTPD(object):  # noqa
    """
  HTTP Server implementation that attaches to an event loop and socket, and
  is capable of handling mesos wire protocol messages.
  """
    def __init__(self, sock, loop):
        """
    Construct an HTTP server on a socket given an ioloop.
    """

        self.loop = loop
        self.sock = sock

        self.app = Application(handlers=[(r'/.*$', Blackhole)])
        self.server = HTTPServer(self.app, io_loop=self.loop)
        self.server.add_sockets([sock])

        self.sock.listen(1024)

    def terminate(self):
        log.info('Terminating HTTP server and all connections')

        self.server.close_all_connections()
        self.sock.close()

    def mount_process(self, process):
        """
    Mount a Process onto the http server to receive message callbacks.
    """

        for route_path in process.route_paths:
            route = '/%s%s' % (process.pid.id, route_path)
            log.info('Mounting route %s' % route)
            self.app.add_handlers('.*$',
                                  [(re.escape(route), RoutedRequestHandler,
                                    dict(process=process, path=route_path))])

        for message_name in process.message_names:
            route = '/%s/%s' % (process.pid.id, message_name)
            log.info('Mounting message handler %s' % route)
            self.app.add_handlers(
                '.*$', [(re.escape(route), WireProtocolMessageHandler,
                         dict(process=process, name=message_name))])

    def unmount_process(self, process):
        """
    Unmount a process from the http server to stop receiving message
    callbacks.
    """

        # There is no remove_handlers, but .handlers is public so why not.  server.handlers is a list of
        # 2-tuples of the form (host_pattern, [list of RequestHandler]) objects.  We filter out all
        # handlers matching our process from the RequestHandler list for each host pattern.
        def nonmatching(handler):
            return 'process' not in handler.kwargs or handler.kwargs[
                'process'] != process

        def filter_handlers(handlers):
            host_pattern, handlers = handlers
            return (host_pattern, list(filter(nonmatching, handlers)))

        self.app.handlers = [
            filter_handlers(handlers) for handlers in self.app.handlers
        ]
コード例 #41
0
ファイル: webserveInit.py プロジェクト: magicseb/SickRage
class SRWebServer(threading.Thread):  # pylint: disable=too-many-instance-attributes
    def __init__(self, options=None, io_loop=None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.alive = True
        self.name = "TORNADO"
        self.io_loop = io_loop or IOLoop.current()

        self.options = options or {}
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', '/')
        assert isinstance(self.options['port'], int)
        assert 'data_root' in self.options

        self.server = None

        # video root
        if sickbeard.ROOT_DIRS:
            root_dirs = sickbeard.ROOT_DIRS.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if self.options['web_root']:
            sickbeard.WEB_ROOT = self.options['web_root'] = ('/' + self.options['web_root'].lstrip('/').strip('/'))

        # api root
        if not sickbeard.API_KEY:
            sickbeard.API_KEY = generateApiKey()
        self.options['api_root'] = r'{0}/api/{1}'.format(sickbeard.WEB_ROOT, sickbeard.API_KEY)

        # tornado setup
        self.enable_https = self.options['enable_https']
        self.https_cert = self.options['https_cert']
        self.https_key = self.options['https_key']

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert and ek(os.path.exists, self.https_cert)) or not (
                    self.https_key and ek(os.path.exists, self.https_key)):
                if not create_https_certificates(self.https_cert, self.https_key):
                    logger.log("Unable to create CERT/KEY files, disabling HTTPS")
                    sickbeard.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (ek(os.path.exists, self.https_cert) and ek(os.path.exists, self.https_key)):
                logger.log("Disabled HTTPS because of missing CERT and KEY files", logger.WARNING)
                sickbeard.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application(
            [],
            debug=True,
            autoreload=False,
            gzip=sickbeard.WEB_USE_GZIP,
            cookie_secret=sickbeard.WEB_COOKIE_SECRET,
            login_url='{0}/login/'.format(self.options['web_root']),
        )

        # Static File Handlers
        self.app.add_handlers(".*$", [
            # favicon
            (r'{0}/(favicon\.ico)'.format(self.options['web_root']), StaticFileHandler,
             {"path": ek(os.path.join, self.options['data_root'], 'images/ico/favicon.ico')}),

            # images
            (r'{0}/images/(.*)'.format(self.options['web_root']), StaticFileHandler,
             {"path": ek(os.path.join, self.options['data_root'], 'images')}),

            # cached images
            (r'{0}/cache/images/(.*)'.format(self.options['web_root']), StaticFileHandler,
             {"path": ek(os.path.join, sickbeard.CACHE_DIR, 'images')}),

            # css
            (r'{0}/css/(.*)'.format(self.options['web_root']), StaticFileHandler,
             {"path": ek(os.path.join, self.options['data_root'], 'css')}),

            # javascript
            (r'{0}/js/(.*)'.format(self.options['web_root']), StaticFileHandler,
             {"path": ek(os.path.join, self.options['data_root'], 'js')}),

            # fonts
            (r'{0}/fonts/(.*)'.format(self.options['web_root']), StaticFileHandler,
             {"path": ek(os.path.join, self.options['data_root'], 'fonts')}),

            # videos
            (r'{0}/videos/(.*)'.format(self.options['web_root']), StaticFileHandler,
             {"path": self.video_root})
        ])

        # Main Handlers
        self.app.add_handlers('.*$', [
            # webapi handler
            (r'{0}(/?.*)'.format(self.options['api_root']), ApiHandler),

            # webapi key retrieval
            (r'{0}/getkey(/?.*)'.format(self.options['web_root']), KeyHandler),

            # webapi builder redirect
            (r'{0}/api/builder'.format(self.options['web_root']), RedirectHandler, {"url": self.options['web_root'] + '/apibuilder/'}),

            # webui login/logout handlers
            (r'{0}/login(/?)'.format(self.options['web_root']), LoginHandler),
            (r'{0}/logout(/?)'.format(self.options['web_root']), LogoutHandler),

            # Web calendar handler (Needed because option Unprotected calendar)
            (r'{0}/calendar'.format(self.options['web_root']), CalendarHandler),

            # webui handlers
        ] + route.get_routes(self.options['web_root']))

    def run(self):
        if self.enable_https:
            protocol = "https"
            ssl_options = {"certfile": self.https_cert, "keyfile": self.https_key}
        else:
            protocol = "http"
            ssl_options = None

        logger.log("Starting SickRage on " + protocol + "://" + str(self.options['host']) + ":" + str(
            self.options['port']) + "/")

        try:
            self.server = self.app.listen(self.options['port'], self.options['host'], ssl_options=ssl_options,
                                          xheaders=sickbeard.HANDLE_REVERSE_PROXY, protocol=protocol)
        except SocketError as ex:
            err_msg = ""
            if ex.errno == errno.EADDRINUSE:  # Address/port combination already in use
                if sickbeard.LAUNCH_BROWSER and not self.daemon:
                    sickbeard.launchBrowser('https' if sickbeard.ENABLE_HTTPS else 'http', self.options['port'], sickbeard.WEB_ROOT)
                    logger.log("Launching browser and exiting")
                err_msg = "already in use!"

            logger.log("Could not start webserver on port {0}: {1}".format(self.options['port'], err_msg or ex))
            os._exit(1)  # pylint: disable=protected-access
        except Exception as ex:
            logger.log("Could not start webserver on port {0}: {1}".format(self.options['port'], ex))
            os._exit(1)  # pylint: disable=protected-access

        try:
            self.io_loop.start()
            self.io_loop.close(True)
        except (IOError, ValueError):
            # Ignore errors like "ValueError: I/O operation on closed kqueue fd". These might be thrown during a reload.
            pass

    def shutdown(self):
        self.alive = False
        self.io_loop.stop()
コード例 #42
0
ファイル: runner.py プロジェクト: jas722/CouchPotatoServer
def runCouchPotato(options, base_path, args, data_dir = None, log_dir = None, Env = None, desktop = None):

    try:
        locale.setlocale(locale.LC_ALL, "")
        encoding = locale.getpreferredencoding()
    except (locale.Error, IOError):
        encoding = None

    # for OSes that are poorly configured I'll just force UTF-8
    if not encoding or encoding in ('ANSI_X3.4-1968', 'US-ASCII', 'ASCII'):
        encoding = 'UTF-8'

    Env.set('encoding', encoding)

    # Do db stuff
    db_path = sp(os.path.join(data_dir, 'database'))

    # Check if database exists
    db = SuperThreadSafeDatabase(db_path)
    db_exists = db.exists()
    if db_exists:

        # Backup before start and cleanup old backups
        backup_path = sp(os.path.join(data_dir, 'db_backup'))
        backup_count = 5
        existing_backups = []
        if not os.path.isdir(backup_path): os.makedirs(backup_path)

        for root, dirs, files in os.walk(backup_path):
            for backup_file in sorted(files):
                ints = re.findall('\d+', backup_file)

                # Delete non zip files
                if len(ints) != 1:
                    os.remove(os.path.join(backup_path, backup_file))
                else:
                    existing_backups.append((int(ints[0]), backup_file))

        # Remove all but the last 5
        for eb in existing_backups[:-backup_count]:
            os.remove(os.path.join(backup_path, eb[1]))

        # Create new backup
        new_backup = sp(os.path.join(backup_path, '%s.tar.gz' % int(time.time())))
        zipf = tarfile.open(new_backup, 'w:gz')
        for root, dirs, files in os.walk(db_path):
            for zfilename in files:
                zipf.add(os.path.join(root, zfilename), arcname = 'database/%s' % os.path.join(root[len(db_path) + 1:], zfilename))
        zipf.close()

        # Open last
        db.open()

    else:
        db.create()

    # Force creation of cachedir
    log_dir = sp(log_dir)
    cache_dir = sp(os.path.join(data_dir, 'cache'))
    python_cache = sp(os.path.join(cache_dir, 'python'))

    if not os.path.exists(cache_dir):
        os.mkdir(cache_dir)
    if not os.path.exists(python_cache):
        os.mkdir(python_cache)

    # Register environment settings
    Env.set('app_dir', sp(base_path))
    Env.set('data_dir', sp(data_dir))
    Env.set('log_path', sp(os.path.join(log_dir, 'CouchPotato.log')))
    Env.set('db', db)
    Env.set('cache_dir', cache_dir)
    Env.set('cache', FileSystemCache(python_cache))
    Env.set('console_log', options.console_log)
    Env.set('quiet', options.quiet)
    Env.set('desktop', desktop)
    Env.set('daemonized', options.daemon)
    Env.set('args', args)
    Env.set('options', options)

    # Determine debug
    debug = options.debug or Env.setting('debug', default = False, type = 'bool')
    Env.set('debug', debug)

    # Development
    development = Env.setting('development', default = False, type = 'bool')
    Env.set('dev', development)

    # Disable logging for some modules
    for logger_name in ['enzyme', 'guessit', 'subliminal', 'apscheduler', 'tornado', 'requests']:
        logging.getLogger(logger_name).setLevel(logging.ERROR)

    for logger_name in ['gntp']:
        logging.getLogger(logger_name).setLevel(logging.WARNING)

    # Use reloader
    reloader = debug is True and development and not Env.get('desktop') and not options.daemon

    # Logger
    logger = logging.getLogger()
    formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s', '%m-%d %H:%M:%S')
    level = logging.DEBUG if debug else logging.INFO
    logger.setLevel(level)
    logging.addLevelName(19, 'INFO')

    # To screen
    if (debug or options.console_log) and not options.quiet and not options.daemon:
        hdlr = logging.StreamHandler(sys.stderr)
        hdlr.setFormatter(formatter)
        logger.addHandler(hdlr)

    # To file
    hdlr2 = handlers.RotatingFileHandler(Env.get('log_path'), 'a', 500000, 10, encoding = Env.get('encoding'))
    hdlr2.setFormatter(formatter)
    logger.addHandler(hdlr2)

    # Start logging & enable colors
    # noinspection PyUnresolvedReferences
    import color_logs
    from couchpotato.core.logger import CPLog
    log = CPLog(__name__)
    log.debug('Started with options %s', options)

    def customwarn(message, category, filename, lineno, file = None, line = None):
        log.warning('%s %s %s line:%s', (category, message, filename, lineno))
    warnings.showwarning = customwarn

    # Create app
    from couchpotato import WebHandler
    web_base = ('/' + Env.setting('url_base').lstrip('/') + '/') if Env.setting('url_base') else '/'
    Env.set('web_base', web_base)

    api_key = Env.setting('api_key')
    if not api_key:
        api_key = uuid4().hex
        Env.setting('api_key', value = api_key)

    api_base = r'%sapi/%s/' % (web_base, api_key)
    Env.set('api_base', api_base)

    # Basic config
    host = Env.setting('host', default = '0.0.0.0')
    # app.debug = development
    config = {
        'use_reloader': reloader,
        'port': tryInt(Env.setting('port', default = 5050)),
        'host': host if host and len(host) > 0 else '0.0.0.0',
        'ssl_cert': Env.setting('ssl_cert', default = None),
        'ssl_key': Env.setting('ssl_key', default = None),
    }

    # Load the app
    application = Application(
        [],
        log_function = lambda x: None,
        debug = config['use_reloader'],
        gzip = True,
        cookie_secret = api_key,
        login_url = '%slogin/' % web_base,
    )
    Env.set('app', application)

    # Request handlers
    application.add_handlers(".*$", [
        (r'%snonblock/(.*)(/?)' % api_base, NonBlockHandler),

        # API handlers
        (r'%s(.*)(/?)' % api_base, ApiHandler),  # Main API handler
        (r'%sgetkey(/?)' % web_base, KeyHandler),  # Get API key
        (r'%s' % api_base, RedirectHandler, {"url": web_base + 'docs/'}),  # API docs

        # Login handlers
        (r'%slogin(/?)' % web_base, LoginHandler),
        (r'%slogout(/?)' % web_base, LogoutHandler),

        # Catch all webhandlers
        (r'%s(.*)(/?)' % web_base, WebHandler),
        (r'(.*)', WebHandler),
    ])

    # Static paths
    static_path = '%sstatic/' % web_base
    for dir_name in ['fonts', 'images', 'scripts', 'style']:
        application.add_handlers(".*$", [
            ('%s%s/(.*)' % (static_path, dir_name), StaticFileHandler, {'path': sp(os.path.join(base_path, 'couchpotato', 'static', dir_name))})
        ])
    Env.set('static_path', static_path)

    # Load configs & plugins
    loader = Env.get('loader')
    loader.preload(root = sp(base_path))
    loader.run()

    # Fill database with needed stuff
    fireEvent('database.setup')
    if not db_exists:
        fireEvent('app.initialize', in_order = True)
    fireEvent('app.migrate')

    # Go go go!
    from tornado.ioloop import IOLoop
    from tornado.autoreload import add_reload_hook
    loop = IOLoop.current()

    # Reload hook
    def test():
        fireEvent('app.shutdown')
    add_reload_hook(test)

    # Some logging and fire load event
    try: log.info('Starting server on port %(port)s', config)
    except: pass
    fireEventAsync('app.load')

    if config['ssl_cert'] and config['ssl_key']:
        server = HTTPServer(application, no_keep_alive = True, ssl_options = {
            'certfile': config['ssl_cert'],
            'keyfile': config['ssl_key'],
        })
    else:
        server = HTTPServer(application, no_keep_alive = True)

    try_restart = True
    restart_tries = 5

    while try_restart:
        try:
            server.listen(config['port'], config['host'])
            loop.start()
        except Exception as e:
            log.error('Failed starting: %s', traceback.format_exc())
            try:
                nr, msg = e
                if nr == 48:
                    log.info('Port (%s) needed for CouchPotato is already in use, try %s more time after few seconds', (config.get('port'), restart_tries))
                    time.sleep(1)
                    restart_tries -= 1

                    if restart_tries > 0:
                        continue
                    else:
                        return
            except:
                pass

            raise

        try_restart = False
コード例 #43
0
class SRWebServer(threading.Thread):
    def __init__(self, options={}, io_loop=None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.alive = True
        self.name = "TORNADO"
        self.io_loop = io_loop or IOLoop.current()

        self.options = options
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', '/')
        assert isinstance(self.options[b'port'], int)
        assert 'data_root' in self.options

        # video root
        if sickbeard.ROOT_DIRS:
            root_dirs = sickbeard.ROOT_DIRS.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if self.options[b'web_root']:
            sickbeard.WEB_ROOT = self.options[b'web_root'] = (
                '/' + self.options[b'web_root'].lstrip('/').strip('/'))

        # api root
        if not sickbeard.API_KEY:
            sickbeard.API_KEY = generateApiKey()
        self.options[b'api_root'] = r'%s/api/%s' % (sickbeard.WEB_ROOT,
                                                    sickbeard.API_KEY)

        # tornado setup
        self.enable_https = self.options[b'enable_https']
        self.https_cert = self.options[b'https_cert']
        self.https_key = self.options[b'https_key']

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert
                    and ek(os.path.exists, self.https_cert)) or not (
                        self.https_key and ek(os.path.exists, self.https_key)):
                if not create_https_certificates(self.https_cert,
                                                 self.https_key):
                    logging.info(
                        "Unable to create CERT/KEY files, disabling HTTPS")
                    sickbeard.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (os.path.exists(self.https_cert)
                    and ek(os.path.exists, self.https_key)):
                logging.warning(
                    "Disabled HTTPS because of missing CERT and KEY files")
                sickbeard.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application(
            [],
            debug=sickbeard.DEBUG,
            autoreload=False,
            gzip=sickbeard.WEB_USE_GZIP,
            xheaders=sickbeard.HANDLE_REVERSE_PROXY,
            cookie_secret=sickbeard.WEB_COOKIE_SECRET,
            login_url='%s/login/' % self.options[b'web_root'],
        )

        # Main Handlers
        self.app.add_handlers(
            '.*$',
            [
                # webapi handler
                (r'%s(/?.*)' % self.options[b'api_root'], ApiHandler),

                # webapi key retrieval
                (r'%s/getkey(/?.*)' % self.options[b'web_root'], KeyHandler),

                # webapi builder redirect
                (r'%s/api/builder' % self.options[b'web_root'],
                 RedirectHandler, {
                     "url": self.options[b'web_root'] + '/apibuilder/'
                 }),

                # webui login/logout handlers
                (r'%s/login(/?)' % self.options[b'web_root'], LoginHandler),
                (r'%s/logout(/?)' % self.options[b'web_root'], LogoutHandler),

                # webui handlers
            ] + route.get_routes(self.options[b'web_root']))

        # Web calendar handler (Needed because option Unprotected calendar)
        self.app.add_handlers('.*$', [
            (r'%s/calendar' % self.options[b'web_root'], CalendarHandler),
        ])

        # Static File Handlers
        self.app.add_handlers(
            ".*$",
            [
                # favicon
                (r'%s/(favicon\.ico)' % self.options[b'web_root'],
                 StaticFileHandler, {
                     "path":
                     ek(os.path.join, self.options[b'data_root'],
                        'images/ico/favicon.ico')
                 }),

                # images
                (r'%s/images/(.*)' % self.options[b'web_root'],
                 StaticFileHandler, {
                     "path": ek(os.path.join, self.options[b'data_root'],
                                'images')
                 }),

                # cached images
                (r'%s/cache/images/(.*)' % self.options[b'web_root'],
                 StaticFileHandler, {
                     "path": ek(os.path.join, sickbeard.CACHE_DIR, 'images')
                 }),

                # css
                (r'%s/css/(.*)' % self.options[b'web_root'], StaticFileHandler,
                 {
                     "path": ek(os.path.join, self.options[b'data_root'],
                                'css')
                 }),

                # javascript
                (r'%s/js/(.*)' % self.options[b'web_root'], StaticFileHandler,
                 {
                     "path": ek(os.path.join, self.options[b'data_root'], 'js')
                 }),

                # videos
            ] + [(r'%s/videos/(.*)' % self.options[b'web_root'],
                  StaticFileHandler, {
                      "path": self.video_root
                  })])

    def run(self):
        if self.enable_https:
            protocol = "https"
            self.server = HTTPServer(self.app,
                                     ssl_options={
                                         "certfile": self.https_cert,
                                         "keyfile": self.https_key
                                     })
        else:
            protocol = "http"
            self.server = HTTPServer(self.app)

        logging.info("Starting SiCKRAGE web server on [{}://{}:{}/]".format(
            protocol, self.options[b'host'], self.options[b'port']))

        try:
            self.server.listen(self.options[b'port'], self.options[b'host'])
        except:
            if sickbeard.LAUNCH_BROWSER and not self.daemon:
                sickbeard.launchBrowser(
                    'https' if sickbeard.ENABLE_HTTPS else 'http',
                    self.options[b'port'], sickbeard.WEB_ROOT)
                logging.info("Launching browser and exiting")
            logging.info(
                "Could not start webserver on port %s, already in use!" %
                self.options[b'port'])
            ek(os._exit, 1)

        try:
            self.io_loop.start()
            self.io_loop.close(True)
        except (IOError, ValueError):
            # Ignore errors like "ValueError: I/O operation on closed kqueue fd". These might be thrown during a reload.
            pass

    def shutDown(self):
        self.alive = False
        self.io_loop.stop()
コード例 #44
0
class SRWebServer(threading.Thread):  # pylint: disable=too-many-instance-attributes
    def __init__(self, options=None, io_loop=None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.alive = True
        self.name = "TORNADO"
        self.io_loop = io_loop or IOLoop.current()

        self.options = options or {}
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', '/')
        assert isinstance(self.options['port'], int)
        assert 'data_root' in self.options

        self.server = None

        # video root
        if sickbeard.ROOT_DIRS:
            root_dirs = sickbeard.ROOT_DIRS.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if self.options['web_root']:
            sickbeard.WEB_ROOT = self.options['web_root'] = (
                '/' + self.options['web_root'].lstrip('/').strip('/'))

        # api root
        if not sickbeard.API_KEY:
            sickbeard.API_KEY = generateApiKey()
        self.options['api_root'] = r'{0}/api/{1}'.format(
            sickbeard.WEB_ROOT, sickbeard.API_KEY)

        # tornado setup
        self.enable_https = self.options['enable_https']
        self.https_cert = self.options['https_cert']
        self.https_key = self.options['https_key']

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert
                    and ek(os.path.exists, self.https_cert)) or not (
                        self.https_key and ek(os.path.exists, self.https_key)):
                if not create_https_certificates(self.https_cert,
                                                 self.https_key):
                    logger.log(
                        "Unable to create CERT/KEY files, disabling HTTPS")
                    sickbeard.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (ek(os.path.exists, self.https_cert)
                    and ek(os.path.exists, self.https_key)):
                logger.log(
                    "Disabled HTTPS because of missing CERT and KEY files",
                    logger.WARNING)
                sickbeard.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application(
            [],
            debug=True,
            autoreload=False,
            gzip=sickbeard.WEB_USE_GZIP,
            cookie_secret=sickbeard.WEB_COOKIE_SECRET,
            login_url='{0}/login/'.format(self.options['web_root']),
        )

        # Main Handlers
        self.app.add_handlers(
            '.*$',
            [
                # webapi handler
                (r'{0}(/?.*)'.format(self.options['api_root']), ApiHandler),

                # webapi key retrieval
                (r'{0}/getkey(/?.*)'.format(
                    self.options['web_root']), KeyHandler),

                # webapi builder redirect
                (r'{0}/api/builder'.format(
                    self.options['web_root']), RedirectHandler, {
                        "url": self.options['web_root'] + '/apibuilder/'
                    }),

                # webui login/logout handlers
                (r'{0}/login(/?)'.format(
                    self.options['web_root']), LoginHandler),
                (r'{0}/logout(/?)'.format(
                    self.options['web_root']), LogoutHandler),

                # Web calendar handler (Needed because option Unprotected calendar)
                (r'{0}/calendar'.format(
                    self.options['web_root']), CalendarHandler),

                # webui handlers
            ] + route.get_routes(self.options['web_root']))

        # Static File Handlers
        self.app.add_handlers(
            ".*$",
            [
                # favicon
                (r'{0}/(favicon\.ico)'.format(
                    self.options['web_root']), StaticFileHandler, {
                        "path":
                        ek(os.path.join, self.options['data_root'],
                           'images/ico/favicon.ico')
                    }),

                # images
                (r'{0}/images/(.*)'.format(
                    self.options['web_root']), StaticFileHandler, {
                        "path": ek(os.path.join, self.options['data_root'],
                                   'images')
                    }),

                # locale
                (r'{0}/locale/messages\.json'.format(
                    self.options['web_root']), LocaleFileHandler, {
                        "path":
                        ek(os.path.join, sickbeard.LOCALE_DIR,
                           '{lang_code}/LC_MESSAGES')
                    }),

                # cached images
                (r'{0}/cache/images/(.*)'.format(
                    self.options['web_root']), StaticFileHandler, {
                        "path": ek(os.path.join, sickbeard.CACHE_DIR, 'images')
                    }),

                # css
                (r'{0}/css/(.*)'.format(self.options['web_root']),
                 StaticFileHandler, {
                     "path": ek(os.path.join, self.options['data_root'], 'css')
                 }),

                # javascript
                (r'{0}/js/(.*)'.format(self.options['web_root']),
                 StaticFileHandler, {
                     "path": ek(os.path.join, self.options['data_root'], 'js')
                 }),

                # fonts
                (r'{0}/fonts/(.*)'.format(
                    self.options['web_root']), StaticFileHandler, {
                        "path": ek(os.path.join, self.options['data_root'],
                                   'fonts')
                    }),

                # videos
                (r'{0}/videos/(.*)'.format(
                    self.options['web_root']), StaticFileHandler, {
                        "path": self.video_root
                    })
            ])

    def run(self):
        if self.enable_https:
            protocol = "https"
            ssl_options = {
                "certfile": self.https_cert,
                "keyfile": self.https_key
            }
        else:
            protocol = "http"
            ssl_options = None

        logger.log("Starting SickRage on " + protocol + "://" +
                   str(self.options['host']) + ":" +
                   str(self.options['port']) + "/")

        try:
            self.server = self.app.listen(
                self.options['port'],
                self.options['host'],
                ssl_options=ssl_options,
                xheaders=sickbeard.HANDLE_REVERSE_PROXY,
                protocol=protocol)
        except Exception:
            if sickbeard.LAUNCH_BROWSER and not self.daemon:
                sickbeard.launchBrowser(
                    'https' if sickbeard.ENABLE_HTTPS else 'http',
                    self.options['port'], sickbeard.WEB_ROOT)
                logger.log("Launching browser and exiting")
            logger.log(
                "Could not start webserver on port {0}, already in use!".
                format(self.options['port']))
            os._exit(1)  # pylint: disable=protected-access

        try:
            self.io_loop.start()
            self.io_loop.close(True)
        except (IOError, ValueError):
            # Ignore errors like "ValueError: I/O operation on closed kqueue fd". These might be thrown during a reload.
            pass

    def shutDown(self):
        self.alive = False
        self.io_loop.stop()
コード例 #45
0
    def make_web_app(self):
        # Start with web application routes
        from unmanic.webserver.websocket import UnmanicWebsocketHandler
        app = Application([
            (r"/unmanic/websocket", UnmanicWebsocketHandler),
            (r"/unmanic/downloads/(.*)", DownloadsHandler),
            (r"/(.*)", RedirectHandler, dict(
                url="/unmanic/ui/dashboard/"
            )),
        ], **tornado_settings)

        # Add API routes
        from unmanic.webserver.api_request_router import APIRequestRouter
        app.add_handlers(r'.*', [
            (
                PathMatches(r"/unmanic/api/.*"),
                APIRequestRouter(app)
            ),
        ])

        # Add frontend routes
        from unmanic.webserver.main import MainUIRequestHandler
        app.add_handlers(r'.*', [
            (r"/unmanic/css/(.*)", StaticFileHandler, dict(
                path=tornado_settings['static_css']
            )),
            (r"/unmanic/fonts/(.*)", StaticFileHandler, dict(
                path=tornado_settings['static_fonts']
            )),
            (r"/unmanic/icons/(.*)", StaticFileHandler, dict(
                path=tornado_settings['static_icons']
            )),
            (r"/unmanic/img/(.*)", StaticFileHandler, dict(
                path=tornado_settings['static_img']
            )),
            (r"/unmanic/js/(.*)", StaticFileHandler, dict(
                path=tornado_settings['static_js']
            )),
            (
                PathMatches(r"/unmanic/ui/(.*)"),
                MainUIRequestHandler,
            ),
        ])

        # Add widgets routes
        from unmanic.webserver.plugins import DataPanelRequestHandler
        from unmanic.webserver.plugins import PluginStaticFileHandler
        from unmanic.webserver.plugins import PluginAPIRequestHandler
        app.add_handlers(r'.*', [
            (
                PathMatches(r"/unmanic/panel/[^/]+(/(?!static/|assets$).*)?$"),
                DataPanelRequestHandler
            ),
            (
                PathMatches(r"/unmanic/plugin_api/[^/]+(/(?!static/|assets$).*)?$"),
                PluginAPIRequestHandler
            ),
            (r"/unmanic/panel/.*/static/(.*)", PluginStaticFileHandler, dict(
                path=tornado_settings['static_img']
            )),
        ])

        if self.developer:
            self._log("API Docs - Updating...", level="debug")
            try:
                from unmanic.webserver.api_v2.schema.swagger import generate_swagger_file
                errors = generate_swagger_file()
                for error in errors:
                    self._log(error, level="warn")
                else:
                    self._log("API Docs - Updated successfully", level="debug")
            except Exception as e:
                self._log("Failed to reload API schema", message2=str(e), level="error")

        # Start the Swagger UI. Automatically generated swagger.json can also
        # be served using a separate Swagger-service.
        from swagger_ui import tornado_api_doc
        tornado_api_doc(
            app,
            config_path=os.path.join(os.path.dirname(__file__), "..", "webserver", "docs", "api_schema_v2.json"),
            url_prefix="/unmanic/swagger",
            title="Unmanic application API"
        )

        return app
コード例 #46
0
ファイル: core.py プロジェクト: Eiber/SickRage-Medusa
class SRWebServer(threading.Thread):  # pylint: disable=too-many-instance-attributes
    def __init__(self, options=None, io_loop=None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.alive = True
        self.name = 'TORNADO'
        self.io_loop = io_loop or IOLoop.current()

        self.options = options or {}
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', '/')
        assert isinstance(self.options['port'], int)
        assert 'data_root' in self.options

        self.server = None

        # video root
        if sickbeard.ROOT_DIRS:
            root_dirs = sickbeard.ROOT_DIRS.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if self.options['web_root']:
            sickbeard.WEB_ROOT = self.options['web_root'] = ('/' + self.options['web_root'].lstrip('/').strip('/'))

        # api root
        if not sickbeard.API_KEY:
            sickbeard.API_KEY = generateApiKey()
        self.options['api_root'] = r'{root}/api/{key}'.format(root=sickbeard.WEB_ROOT, key=sickbeard.API_KEY)

        # tornado setup
        self.enable_https = self.options['enable_https']
        self.https_cert = self.options['https_cert']
        self.https_key = self.options['https_key']

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert and ek(os.path.exists, self.https_cert)) or not (
                    self.https_key and ek(os.path.exists, self.https_key)):
                if not create_https_certificates(self.https_cert, self.https_key):
                    logger.log('Unable to create CERT/KEY files, disabling HTTPS')
                    sickbeard.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (ek(os.path.exists, self.https_cert) and ek(os.path.exists, self.https_key)):
                logger.log('Disabled HTTPS because of missing CERT and KEY files', logger.WARNING)
                sickbeard.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application(
            [],
            debug=True,
            autoreload=False,
            gzip=sickbeard.WEB_USE_GZIP,
            xheaders=sickbeard.HANDLE_REVERSE_PROXY,
            cookie_secret=sickbeard.WEB_COOKIE_SECRET,
            login_url=r'{root}/login/'.format(root=self.options['web_root']),
        )

        # Main Handlers
        self.app.add_handlers('.*$', [
            # webapi handler
            (r'{base}(/?.*)'.format(base=self.options['api_root']), ApiHandler),

            # webapi key retrieval
            (r'{base}/getkey(/?.*)'.format(base=self.options['web_root']), KeyHandler),

            # webapi builder redirect
            (r'{base}/api/builder'.format(base=self.options['web_root']),
             RedirectHandler, {'url': '{base}/apibuilder/'.format(base=self.options['web_root'])}),

            # webui login/logout handlers
            (r'{base}/login(/?)'.format(base=self.options['web_root']), LoginHandler),
            (r'{base}/logout(/?)'.format(base=self.options['web_root']), LogoutHandler),

            # Web calendar handler (Needed because option Unprotected calendar)
            (r'{base}/calendar'.format(base=self.options['web_root']), CalendarHandler),

            # webui handlers
        ] + route.get_routes(self.options['web_root']))

        # Static File Handlers
        self.app.add_handlers('.*$', [
            # favicon
            (r'{base}/(favicon\.ico)'.format(base=self.options['web_root']), StaticFileHandler,
             {'path': ek(os.path.join, self.options['data_root'], 'images/ico/favicon.ico')}),

            # images
            (r'{base}/images/(.*)'.format(base=self.options['web_root']), StaticFileHandler,
             {'path': ek(os.path.join, self.options['data_root'], 'images')}),

            # cached images
            (r'{base}/cache/images/(.*)'.format(base=self.options['web_root']), StaticFileHandler,
             {'path': ek(os.path.join, sickbeard.CACHE_DIR, 'images')}),

            # css
            (r'{base}/css/(.*)'.format(base=self.options['web_root']), StaticFileHandler,
             {'path': ek(os.path.join, self.options['data_root'], 'css')}),

            # javascript
            (r'{base}/js/(.*)'.format(base=self.options['web_root']), StaticFileHandler,
             {'path': ek(os.path.join, self.options['data_root'], 'js')}),

            # fonts
            (r'{base}/fonts/(.*)'.format(base=self.options['web_root']), StaticFileHandler,
             {'path': ek(os.path.join, self.options['data_root'], 'fonts')}),

            # videos
            (r'{base}/videos/(.*)'.format(base=self.options['web_root']), StaticFileHandler,
             {'path': self.video_root})
        ])

    def run(self):
        if self.enable_https:
            protocol = 'https'
            self.server = HTTPServer(self.app, ssl_options={'certfile': self.https_cert, 'keyfile': self.https_key})
        else:
            protocol = 'http'
            self.server = HTTPServer(self.app)

        logger.log('Starting Medusa on {scheme}://{host}:{port}/'.format
                   (scheme=protocol, host=self.options['host'], port=self.options['port']))

        try:
            self.server.listen(self.options['port'], self.options['host'])
        except Exception:
            if sickbeard.LAUNCH_BROWSER and not self.daemon:
                sickbeard.launchBrowser('https' if sickbeard.ENABLE_HTTPS else 'http', self.options['port'], sickbeard.WEB_ROOT)
                logger.log('Launching browser and exiting')
            logger.log('Could not start the web server on port {port}, already in use!'.format(port=self.options['port']))
            os._exit(1)  # pylint: disable=protected-access

        try:
            self.io_loop.start()
            self.io_loop.close(True)
        except (IOError, ValueError):
            # Ignore errors like 'ValueError: I/O operation on closed kqueue fd'. These might be thrown during a reload.
            pass

    def shutDown(self):
        self.alive = False
        self.io_loop.stop()
コード例 #47
0
ファイル: server_settings.py プロジェクト: xottl/SickChill
class SRWebServer(threading.Thread):
    def __init__(self, options=None):
        super().__init__()
        self.daemon = True
        self.alive = True
        self.name = "WEBSERVER"

        self.options = options

        if settings.WEB_HOST and settings.WEB_HOST != "0.0.0.0":
            web_host = settings.WEB_HOST
        else:
            web_host = ("0.0.0.0", "")[settings.WEB_IPV6]

        self.options.update({
            "data_root":
            os.path.join(settings.PROG_DIR, "gui", settings.GUI_NAME),
            "web_root":
            settings.WEB_ROOT,
            "host":
            web_host,
            "enable_https":
            settings.ENABLE_HTTPS,
            "handle_reverse_proxy":
            settings.HANDLE_REVERSE_PROXY,
            "log_dir": (None, settings.LOG_DIR)[settings.WEB_LOG],
            # 'username': oldbeard.WEB_USERNAME or '',
            # 'password': oldbeard.WEB_PASSWORD or '',
        })

        self.options.setdefault("port", settings.WEB_PORT or 8081)

        self.server = None

        # video root
        if settings.ROOT_DIRS:
            root_dirs = settings.ROOT_DIRS.split("|")
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if self.options["web_root"]:
            settings.WEB_ROOT = self.options[
                "web_root"] = "/" + self.options["web_root"].strip("/")

        # api root
        if not settings.API_KEY:
            settings.API_KEY = generateApiKey()
        self.options[
            "api_root"] = f"{settings.WEB_ROOT}/api/{settings.API_KEY}"

        # tornado setup
        self.enable_https = self.options["enable_https"]

        self.https_cert = None
        if settings.HTTPS_CERT:
            self.https_cert = os.path.realpath(settings.HTTPS_CERT)
            if not os.path.exists(self.https_cert) and not os.path.isabs(
                    self.https_cert):
                self.https_cert = os.path.realpath(
                    os.path.join(settings.DATA_DIR, settings.HTTPS_CERT))

        self.https_key = None
        if settings.HTTPS_KEY:
            self.https_key = os.path.realpath(settings.HTTPS_KEY)
            if not os.path.exists(self.https_key) and not os.path.isabs(
                    self.https_key):
                self.https_key = os.path.realpath(
                    os.path.join(settings.DATA_DIR, settings.HTTPS_KEY))

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert and os.path.exists(self.https_cert)
                    and self.https_key and os.path.exists(self.https_key)):
                if not create_https_certificates(self.https_cert,
                                                 self.https_key):
                    logger.info(
                        "Unable to create CERT/KEY files, disabling HTTPS")
                    settings.ENABLE_HTTPS = self.enable_https = False

            if not (os.path.exists(self.https_cert)
                    and os.path.exists(self.https_key)):
                logger.warning(
                    "Disabled HTTPS because of missing CERT and KEY files")
                settings.ENABLE_HTTPS = self.enable_https = False

        asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())

        # Load the app
        self.app = Application(
            [],
            debug=
            False,  # enables autoreload, compiled_template_cache, static_hash_cache, serve_traceback - This fixes the 404 page and fixes autoreload for
            #  devs. We could now update without restart possibly if we check DB version hasnt changed!
            autoreload=False,
            gzip=settings.WEB_USE_GZIP,
            cookie_secret=settings.WEB_COOKIE_SECRET,
            login_url=f'{self.options["web_root"]}/login/',
            static_path=self.options["data_root"],
            static_url_prefix=f'{self.options["web_root"]}/',
            static_handler_class=SickChillStaticFileHandler
            # default_handler_class=Custom404Handler
        )

        # Static File Handlers
        self.app.add_handlers(
            ".*$",
            [
                url(
                    rf'{self.options["web_root"]}/(favicon\.ico)',
                    SickChillStaticFileHandler,
                    {
                        "path":
                        os.path.join(self.options["data_root"], "images/ico")
                    },
                    name="favicon",
                ),
                url(
                    rf'{self.options["web_root"]}/images/(.*)',
                    SickChillStaticFileHandler,
                    {
                        "path": os.path.join(self.options["data_root"],
                                             "images")
                    },
                    name="images",
                ),
                url(
                    rf'{self.options["web_root"]}/cache/images/(.*)',
                    SickChillStaticFileHandler,
                    {"path": os.path.join(settings.CACHE_DIR, "images")},
                    name="image_cache",
                ),
                url(rf'{self.options["web_root"]}/css/(.*)',
                    SickChillStaticFileHandler,
                    {"path": os.path.join(self.options["data_root"], "css")},
                    name="css"),
                url(rf'{self.options["web_root"]}/js/(.*)',
                    SickChillStaticFileHandler,
                    {"path": os.path.join(self.options["data_root"], "js")},
                    name="js"),
                url(
                    rf'{self.options["web_root"]}/fonts/(.*)',
                    SickChillStaticFileHandler,
                    {"path": os.path.join(self.options["data_root"], "fonts")},
                    name="fonts",
                )
                # TODO: WTF is this?
                # url(rf'{self.options["web_root"]}/videos/(.*)', SickChillStaticFileHandler,
                #     {"path": self.video_root}, name='videos')
            ],
        )

        # Main Handlers
        self.app.add_handlers(
            ".*$",
            [
                url(rf'{self.options["api_root"]}(/?.*)',
                    ApiHandler,
                    name="api"),
                url(rf'{self.options["web_root"]}/getkey(/?.*)',
                    KeyHandler,
                    name="get_api_key"),
                url(rf'{self.options["web_root"]}/api/builder',
                    RedirectHandler,
                    {"url": self.options["web_root"] + "/apibuilder/"},
                    name="apibuilder"),
                url(rf'{self.options["web_root"]}/login(/?)',
                    LoginHandler,
                    name="login"),
                url(rf'{self.options["web_root"]}/logout(/?)',
                    LogoutHandler,
                    name="logout"),
                url(rf'{self.options["web_root"]}/calendar/?',
                    CalendarHandler,
                    name="calendar"),
                url(rf'{self.options["web_root"]}/movies/(?P<route>details)/(?P<slug>.*)/',
                    MoviesHandler,
                    name="movies-details"),
                url(rf'{self.options["web_root"]}/movies/(?P<route>remove)/(?P<pk>.*)/',
                    MoviesHandler,
                    name="movies-remove"),
                url(rf'{self.options["web_root"]}/movies/(?P<route>add)/',
                    MoviesHandler,
                    name="movies-add"),
                url(rf'{self.options["web_root"]}/movies/(?P<route>search)/',
                    MoviesHandler,
                    name="movies-search"),
                url(rf'{self.options["web_root"]}/movies/(?P<route>list)/',
                    MoviesHandler,
                    name="movies-list"),
                url(rf'{self.options["web_root"]}/movies/(.*)',
                    MoviesHandler,
                    name="movies"),
                # routes added by @route decorator
                # Plus naked index with missing web_root prefix
            ] + Route.get_routes(self.options["web_root"]),
        )

    def run(self):
        if self.enable_https:
            protocol = "https"
            ssl_options = {
                "certfile": self.https_cert,
                "keyfile": self.https_key
            }
        else:
            protocol = "http"
            ssl_options = None

        logger.info("Starting SickChill on " + protocol + "://" +
                    str(self.options["host"]) + ":" +
                    str(self.options["port"]) + "/")

        try:
            self.server = self.app.listen(
                self.options["port"],
                self.options["host"],
                ssl_options=ssl_options,
                xheaders=settings.HANDLE_REVERSE_PROXY,
                protocol=protocol)
        except socket_error as ex:
            err_msg = ""
            if ex.errno == errno.EADDRINUSE:  # Address/port combination already in use
                if settings.LAUNCH_BROWSER and not self.daemon:
                    sickchill.start.launchBrowser(
                        "https" if settings.ENABLE_HTTPS else "http",
                        self.options["port"], settings.WEB_ROOT)
                    logger.info("Launching browser and exiting")
                err_msg = "already in use!"

            logger.info(
                f"Could not start webserver on port {self.options['port']}: {err_msg or ex}"
            )
            # noinspection PyProtectedMember
            os._exit(1)
        except Exception as ex:
            logger.info(
                f"Could not start webserver on port {self.options['port']}: {ex}"
            )

            # noinspection PyProtectedMember
            os._exit(1)

        try:
            IOLoop.current().start()
            IOLoop.current().close(True)
        except (IOError, ValueError):
            # Ignore errors like "ValueError: I/O operation on closed kqueue fd". These might be thrown during a reload.
            pass

    def shutdown(self):
        self.alive = False
        IOLoop.current().stop()
コード例 #48
0
ファイル: core.py プロジェクト: steflavoie/Medusa
class AppWebServer(threading.Thread):  # pylint: disable=too-many-instance-attributes
    def __init__(self, options=None, io_loop=None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.alive = True
        self.name = 'TORNADO'
        self.io_loop = io_loop or IOLoop.current()

        self.options = options or {}
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', '/')
        assert isinstance(self.options['port'], int)
        assert 'data_root' in self.options

        self.server = None

        # video root
        if app.ROOT_DIRS:
            root_dirs = app.ROOT_DIRS
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if self.options['web_root']:
            app.WEB_ROOT = self.options['web_root'] = ('/' + self.options['web_root'].lstrip('/').strip('/'))

        # api root
        if not app.API_KEY:
            app.API_KEY = generate_api_key()
        self.options['api_root'] = r'{root}/api/(?:v1/)?{key}'.format(root=app.WEB_ROOT, key=app.API_KEY)
        self.options['api_v2_root'] = r'{root}/api/v2'.format(root=app.WEB_ROOT)

        # websocket root
        self.options['web_socket'] = r'{root}/ws'.format(root=app.WEB_ROOT)

        # tornado setup
        self.enable_https = self.options['enable_https']
        self.https_cert = self.options['https_cert']
        self.https_key = self.options['https_key']

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert and os.path.exists(self.https_cert)) or not (
                    self.https_key and os.path.exists(self.https_key)):
                if not create_https_certificates(self.https_cert, self.https_key):
                    logger.log('Unable to create CERT/KEY files, disabling HTTPS')
                    app.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (os.path.exists(self.https_cert) and os.path.exists(self.https_key)):
                logger.log('Disabled HTTPS because of missing CERT and KEY files', logger.WARNING)
                app.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application(
            [],
            debug=True,
            autoreload=False,
            gzip=app.WEB_USE_GZIP,
            xheaders=app.HANDLE_REVERSE_PROXY,
            cookie_secret=app.WEB_COOKIE_SECRET,
            login_url=r'{root}/login/'.format(root=self.options['web_root']),
        )

        self.app.add_handlers('.*$', get_apiv2_handlers(self.options['api_v2_root']))

        # Websocket handler
        self.app.add_handlers(".*$", [
            (r'{base}/ui(/?.*)'.format(base=self.options['web_socket']), MedusaWebSocketHandler.WebSocketUIHandler)
        ])

        # Static File Handlers
        self.app.add_handlers('.*$', [
            # favicon
            (r'{base}/(favicon\.ico)'.format(base=self.options['web_root']), StaticFileHandler,
             {'path': os.path.join(self.options['data_root'], 'images/ico/favicon.ico')}),

            # images
            (r'{base}/images/(.*)'.format(base=self.options['web_root']), StaticFileHandler,
             {'path': os.path.join(self.options['data_root'], 'images')}),

            # cached images
            (r'{base}/cache/images/(.*)'.format(base=self.options['web_root']), StaticFileHandler,
             {'path': os.path.join(app.CACHE_DIR, 'images')}),

            # css
            (r'{base}/css/(.*)'.format(base=self.options['web_root']), StaticFileHandler,
             {'path': os.path.join(self.options['data_root'], 'css')}),

            # javascript
            (r'{base}/js/(.*)'.format(base=self.options['web_root']), StaticFileHandler,
             {'path': os.path.join(self.options['data_root'], 'js')}),

            # fonts
            (r'{base}/fonts/(.*)'.format(base=self.options['web_root']), StaticFileHandler,
             {'path': os.path.join(self.options['data_root'], 'fonts')}),

            # videos
            (r'{base}/videos/(.*)'.format(base=self.options['web_root']), StaticFileHandler,
             {'path': self.video_root}),

            # vue dist
            (r'{base}/vue/dist/(.*)'.format(base=self.options['web_root']), StaticFileHandler,
             {'path': os.path.join(self.options['vue_root'], 'dist')}),

            # vue index.html
            (r'{base}/vue/?.*()'.format(base=self.options['web_root']), AuthenticatedStaticFileHandler,
             {'path': os.path.join(self.options['vue_root'], 'index.html'), 'default_filename': 'index.html'}),
        ])

        # API v1 handlers
        self.app.add_handlers('.*$', [
            # Main handler
            (r'{base}(/?.*)'.format(base=self.options['api_root']), ApiHandler),

            # Key retrieval
            (r'{base}/getkey(/?.*)'.format(base=self.options['web_root']), KeyHandler),

            # Builder redirect
            (r'{base}/api/builder'.format(base=self.options['web_root']),
             RedirectHandler, {'url': '{base}/apibuilder/'.format(base=self.options['web_root'])}),

            # Webui login/logout handlers
            (r'{base}/login(/?)'.format(base=self.options['web_root']), LoginHandler),
            (r'{base}/logout(/?)'.format(base=self.options['web_root']), LogoutHandler),

            (r'{base}/token(/?)'.format(base=self.options['web_root']), TokenHandler),

            # Web calendar handler (Needed because option Unprotected calendar)
            (r'{base}/calendar'.format(base=self.options['web_root']), CalendarHandler),

            # webui handlers
        ] + self._get_webui_routes())

    def _get_webui_routes(self):
        webroot = self.options['web_root']
        route._routes = list(reversed([url(webroot + u.regex.pattern, u.handler_class, u.kwargs, u.name) for u in route.get_routes()]))
        return route.get_routes()

    def run(self):
        if self.enable_https:
            protocol = 'https'
            self.server = HTTPServer(self.app, ssl_options={'certfile': self.https_cert, 'keyfile': self.https_key})
        else:
            protocol = 'http'
            self.server = HTTPServer(self.app)

        logger.log('Starting Medusa on {scheme}://{host}:{port}{web_root}/'.format
                   (scheme=protocol,
                    host=self.options['host'],
                    port=self.options['port'],
                    web_root=self.options['web_root']))

        try:
            self.server.listen(self.options['port'], self.options['host'])
        except Exception:
            if app.LAUNCH_BROWSER and not self.daemon:
                app.instance.launch_browser('https' if app.ENABLE_HTTPS else 'http', self.options['port'], app.WEB_ROOT)
                logger.log('Launching browser and exiting')
            logger.log('Could not start the web server on port {port}, already in use!'.format(port=self.options['port']))
            os._exit(1)  # pylint: disable=protected-access

        try:
            self.io_loop.start()
            self.io_loop.close(True)
        except (IOError, ValueError):
            # Ignore errors like 'ValueError: I/O operation on closed kqueue fd'. These might be thrown during a reload.
            pass

    def shutDown(self):
        self.alive = False
        self.io_loop.stop()
コード例 #49
0
class SRWebServer(threading.Thread):
    def __init__(self, options={}, io_loop=None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.alive = True
        self.name = "TORNADO"
        self.io_loop = io_loop or IOLoop.current()

        self.options = options
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', None)
        assert isinstance(self.options['port'], int)
        assert 'data_root' in self.options

        # video root
        if sickbeard.ROOT_DIRS:
            root_dirs = sickbeard.ROOT_DIRS.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        self.options['web_root'] = ('/' + self.options['web_root'].lstrip('/')
                                    ) if self.options['web_root'] else ''

        # tornado setup
        self.enable_https = self.options['enable_https']
        self.https_cert = self.options['https_cert']
        self.https_key = self.options['https_key']

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert
                    and os.path.exists(self.https_cert)) or not (
                        self.https_key and os.path.exists(self.https_key)):
                if not create_https_certificates(self.https_cert,
                                                 self.https_key):
                    logger.log(
                        u"Unable to create CERT/KEY files, disabling HTTPS")
                    sickbeard.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (os.path.exists(self.https_cert)
                    and os.path.exists(self.https_key)):
                logger.log(
                    u"Disabled HTTPS because of missing CERT and KEY files",
                    logger.WARNING)
                sickbeard.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application(
            [],
            debug=True,
            autoreload=False,
            gzip=True,
            xheaders=sickbeard.HANDLE_REVERSE_PROXY,
            cookie_secret='61oETzKXQAGaYdkL5gEmGeJJFuYh7EQnp2XdTP1o/Vo=')

        # Main Handler
        self.app.add_handlers(
            ".*$",
            [(r'%s/api/(.*)(/?)' % self.options['web_root'], webapi.Api),
             (r'%s/(.*)(/?)' % self.options['web_root'], webserve.MainHandler),
             (r'(.*)', webserve.MainHandler)])

        # Static Path Handler
        self.app.add_handlers(".*$", [
            (r'%s/(favicon\.ico)' % self.options['web_root'],
             MultiStaticFileHandler, {
                 'paths': [
                     os.path.join(self.options['data_root'],
                                  'images/ico/favicon.ico')
                 ]
             }),
            (r'%s/%s/(.*)(/?)' %
             (self.options['web_root'], 'images'), MultiStaticFileHandler, {
                 'paths': [
                     os.path.join(self.options['data_root'], 'images'),
                     os.path.join(sickbeard.CACHE_DIR, 'images')
                 ]
             }),
            (r'%s/%s/(.*)(/?)' %
             (self.options['web_root'], 'css'), MultiStaticFileHandler, {
                 'paths': [os.path.join(self.options['data_root'], 'css')]
             }),
            (r'%s/%s/(.*)(/?)' %
             (self.options['web_root'], 'js'), MultiStaticFileHandler, {
                 'paths': [os.path.join(self.options['data_root'], 'js')]
             }),
        ])

        # Static Videos Path
        if self.video_root:
            self.app.add_handlers(".*$", [
                (r'%s/%s/(.*)' % (self.options['web_root'], 'videos'),
                 MultiStaticFileHandler, {
                     'paths': [self.video_root]
                 }),
            ])

    def run(self):
        if self.enable_https:
            protocol = "https"
            self.server = HTTPServer(self.app,
                                     ssl_options={
                                         "certfile": self.https_cert,
                                         "keyfile": self.https_key
                                     })
        else:
            protocol = "http"
            self.server = HTTPServer(self.app)

        logger.log(u"Starting SickRage on " + protocol + "://" +
                   str(self.options['host']) + ":" +
                   str(self.options['port']) + "/")

        try:
            self.server.listen(self.options['port'], self.options['host'])
        except:
            etype, evalue, etb = sys.exc_info()
            logger.log(
                "Could not start webserver on %s. Excpeption: %s, Error: %s" %
                (self.options['port'], etype, evalue), logger.ERROR)
            return

        try:
            self.io_loop.start()
            self.io_loop.close(True)
        except (IOError, ValueError):
            # Ignore errors like "ValueError: I/O operation on closed kqueue fd". These might be thrown during a reload.
            pass

    def shutDown(self):
        self.alive = False
        if self.server:
            self.server.stop()
            self.io_loop.stop()
コード例 #50
0
ファイル: server_settings.py プロジェクト: xelgand/SickChill
class SRWebServer(threading.Thread):
    def __init__(self, options=None):
        threading.Thread.__init__(self)
        self.daemon = True
        self.alive = True
        self.name = "WEBSERVER"

        self.options = options or {}
        self.options.setdefault('port', 8081)
        self.options.setdefault('host', '0.0.0.0')
        self.options.setdefault('log_dir', None)
        self.options.setdefault('username', '')
        self.options.setdefault('password', '')
        self.options.setdefault('web_root', '/')

        assert isinstance(self.options['port'], int)
        assert 'data_root' in self.options

        self.server = None

        # video root
        if sickbeard.ROOT_DIRS:
            root_dirs = sickbeard.ROOT_DIRS.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]
        else:
            self.video_root = None

        # web root
        if self.options['web_root']:
            sickbeard.WEB_ROOT = self.options['web_root'] = (
                '/' + self.options['web_root'].lstrip('/').strip('/'))

        # api root
        if not sickbeard.API_KEY:
            sickbeard.API_KEY = generateApiKey()
        self.options['api_root'] = r'{0}/api/{1}'.format(
            sickbeard.WEB_ROOT, sickbeard.API_KEY)

        # tornado setup
        self.enable_https = self.options['enable_https']
        self.https_cert = self.options['https_cert']
        self.https_key = self.options['https_key']

        if self.enable_https:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (self.https_cert
                    and ek(os.path.exists, self.https_cert)) or not (
                        self.https_key and ek(os.path.exists, self.https_key)):
                if not create_https_certificates(self.https_cert,
                                                 self.https_key):
                    logger.log(
                        "Unable to create CERT/KEY files, disabling HTTPS")
                    sickbeard.ENABLE_HTTPS = False
                    self.enable_https = False

            if not (ek(os.path.exists, self.https_cert)
                    and ek(os.path.exists, self.https_key)):
                logger.log(
                    "Disabled HTTPS because of missing CERT and KEY files",
                    logger.WARNING)
                sickbeard.ENABLE_HTTPS = False
                self.enable_https = False

        # Load the app
        self.app = Application(
            [],
            debug=
            False,  # enables autoreload, compiled_template_cache, static_hash_cache, serve_traceback - This fixes the 404 page and fixes autoreload for
            #  devs. We could now update without restart possibly if we check DB version hasnt changed!
            autoreload=False,
            gzip=sickbeard.WEB_USE_GZIP,
            cookie_secret=sickbeard.WEB_COOKIE_SECRET,
            login_url='{0}/login/'.format(self.options['web_root']),
            static_path=self.options['data_root'],
            static_url_prefix='{0}/'.format(self.options['web_root'])
            # default_handler_class=Custom404Handler
        )

        # Static File Handlers
        self.app.add_handlers(
            ".*$",
            [
                url(r'{0}/favicon.ico'.format(self.options['web_root']),
                    StaticFileHandler, {
                        "path":
                        ek(os.path.join, self.options['data_root'],
                           'images/ico/favicon.ico')
                    },
                    name='favicon'),
                url(r'{0}/images/(.*)'.format(self.options['web_root']),
                    StaticFileHandler, {
                        "path":
                        ek(os.path.join, self.options['data_root'], 'images')
                    },
                    name='images'),
                url(r'{0}/cache/images/(.*)'.format(self.options['web_root']),
                    StaticFileHandler,
                    {"path": ek(os.path.join, sickbeard.CACHE_DIR, 'images')},
                    name='image_cache'),
                url(r'{0}/css/(.*)'.format(self.options['web_root']),
                    StaticFileHandler, {
                        "path": ek(os.path.join, self.options['data_root'],
                                   'css')
                    },
                    name='css'),
                url(r'{0}/js/(.*)'.format(self.options['web_root']),
                    StaticFileHandler, {
                        "path": ek(os.path.join, self.options['data_root'],
                                   'js')
                    },
                    name='js'),
                url(r'{0}/fonts/(.*)'.format(self.options['web_root']),
                    StaticFileHandler, {
                        "path":
                        ek(os.path.join, self.options['data_root'], 'fonts')
                    },
                    name='fonts')

                # TODO: WTF is this?
                # url(r'{0}/videos/(.*)'.format(self.options['web_root']), StaticFileHandler,
                #     {"path": self.video_root}, name='videos')
            ])

        # Main Handlers
        self.app.add_handlers(
            '.*$',
            [
                url(r'{0}(/?.*)'.format(self.options['api_root']),
                    ApiHandler,
                    name='api'),
                url(r'{0}/getkey(/?.*)'.format(self.options['web_root']),
                    KeyHandler,
                    name='get_api_key'),
                url(r'{0}/api/builder'.format(self.options['web_root']),
                    RedirectHandler,
                    {"url": self.options['web_root'] + '/apibuilder/'},
                    name='apibuilder'),
                url(r'{0}/login(/?)'.format(self.options['web_root']),
                    LoginHandler,
                    name='login'),
                url(r'{0}/logout(/?)'.format(self.options['web_root']),
                    LogoutHandler,
                    name='logout'),
                url(r'{0}/calendar/?'.format(self.options['web_root']),
                    CalendarHandler,
                    name='calendar'),

                # routes added by @route decorator
                # Plus naked index with missing web_root prefix
            ] + Route.get_routes(self.options['web_root']))

    def run(self):
        if self.enable_https:
            protocol = "https"
            ssl_options = {
                "certfile": self.https_cert,
                "keyfile": self.https_key
            }
        else:
            protocol = "http"
            ssl_options = None

        logger.log("Starting SickChill on " + protocol + "://" +
                   str(self.options['host']) + ":" +
                   str(self.options['port']) + "/")

        try:
            self.server = self.app.listen(
                self.options['port'],
                self.options['host'],
                ssl_options=ssl_options,
                xheaders=sickbeard.HANDLE_REVERSE_PROXY,
                protocol=protocol)
        except socket_error as ex:
            err_msg = ""
            if ex.errno == errno.EADDRINUSE:  # Address/port combination already in use
                if sickbeard.LAUNCH_BROWSER and not self.daemon:
                    sickbeard.launchBrowser(
                        'https' if sickbeard.ENABLE_HTTPS else 'http',
                        self.options['port'], sickbeard.WEB_ROOT)
                    logger.log("Launching browser and exiting")
                err_msg = "already in use!"

            logger.log("Could not start webserver on port {0}: {1}".format(
                self.options['port'], err_msg or ex))
            # noinspection PyProtectedMember
            os._exit(1)
        except Exception as ex:
            logger.log("Could not start webserver on port {0}: {1}".format(
                self.options['port'], ex))

            # noinspection PyProtectedMember
            os._exit(1)

        try:
            IOLoop.current().start()
            IOLoop.current().close(True)
        except (IOError, ValueError) as e:
            # Ignore errors like "ValueError: I/O operation on closed kqueue fd". These might be thrown during a reload.
            pass

    def shutdown(self):
        self.alive = False
        IOLoop.current().stop()
コード例 #51
0
class APIManager(EService):
    """Service exposing the 5G-EmPOWER REST API

    This service exposes the 5G-EmPOWER REST API, the 'port' parameter
    specifies on which port the HTTP server should listen.

    Parameters:
        port: the port on which the HTTP server should listen (optional,
            default: 8888)
    """

    HANDLERS = [IndexHandler, AuthLoginHandler, AuthLogoutHandler,
                DocHandler, AuthSwitchProjectHandler]

    accounts_manager = None
    projects_manager = None

    def __init__(self, context, service_id, webui, port):

        super().__init__(context=context, service_id=service_id, webui=webui,
                         port=port)

        self.settings = {
            "static_path": self.webui + "static/",
            "cookie_secret": COOKIE_SECRET,
            "template_path": self.webui + "templates/",
            "login_url": LOGIN_URL,
            "debug": DEBUG,
        }

        self.application = Application([], **self.settings)

        self.http_server = tornado.httpserver.HTTPServer(self.application)

    @property
    def webui(self):
        """Return path to Web UI."""

        return self.params["webui"]

    @webui.setter
    def webui(self, value):
        """Set path to Web UI."""

        if "webui" in self.params and self.params["webui"]:
            raise ValueError("Param webui can not be changed")

        self.params["webui"] = value

    @property
    def port(self):
        """Return port."""

        return self.params["port"]

    @port.setter
    def port(self, value):
        """Set port."""

        if "port" in self.params and self.params["port"]:
            raise ValueError("Param port can not be changed")

        self.params["port"] = int(value)

    def start(self):
        """Start api manager."""

        super().start()

        self.accounts_manager = srv_or_die("accountsmanager")
        self.projects_manager = srv_or_die("projectsmanager")

        self.http_server.listen(self.port)

        self.log.info("Listening on port %u", self.port)

        self.http_server.start()

    def register_handler(self, handler):
        """Add a new handler class."""

        for url in handler.URLS:
            self.log.info("Registering URL: %s", url)
            self.application.add_handlers(r".*$", [(url, handler)])
コード例 #52
0
ファイル: apimanager.py プロジェクト: cnxtech/empower-runtime
class APIManager(EService):
    """Service exposing the 5G-EmPOWER REST API

    This service exposes the 5G-EmPOWER REST API, the 'port' parameter
    specifies on which port the HTTP server should listen.

    Parameters:
        port: the port on which the HTTP server should listen (optional,
            default: 8888)
    """

    HANDLERS = [IndexHandler, AuthLoginHandler, AuthLogoutHandler,
                DocHandler]

    accounts_manager = None
    projects_manager = None

    def __init__(self, **kwargs):

        if 'port' not in kwargs:
            kwargs['port'] = DEFAULT_PORT

        super().__init__(**kwargs)

        self.settings = {
            "static_path": STATIC_PATH,
            "cookie_secret": COOKIE_SECRET,
            "template_path": TEMPLATE_PATH,
            "login_url": LOGIN_URL,
            "debug": DEBUG,
        }

        self.application = Application([], **self.settings)

        self.http_server = tornado.httpserver.HTTPServer(self.application)

    @property
    def port(self):
        """Return port."""

        return self.params["port"]

    @port.setter
    def port(self, value):
        """Set port."""

        if "port" in self.params and self.params["port"]:
            raise ValueError("Param port can not be changed")

        self.params["port"] = int(value)

    def start(self, load):
        """Start api manager."""

        super().start(load)

        self.accounts_manager = \
            srv_or_die("empower.managers.accountsmanager.accountsmanager")

        self.projects_manager = \
            srv_or_die("empower.managers.projectsmanager.projectsmanager")

        self.http_server.listen(self.port)

        self.log.info("Listening on port %u", self.port)

        self.http_server.start()

    def register_handler(self, handler):
        """Add a new handler class."""

        for url in handler.URLS:
            self.log.info("Registering URL: %s", url)
            self.application.add_handlers(r".*$", [(url, handler)])
コード例 #53
0
ファイル: __init__.py プロジェクト: djenniex/SickBeard-TVRage
class srWebServer(object):
    def __init__(self):
        self.started = False

    def start(self):
        self.started = True

        # video root
        self.video_root = None
        if sickrage.srCore.srConfig.ROOT_DIRS:
            root_dirs = sickrage.srCore.srConfig.ROOT_DIRS.split('|')
            self.video_root = root_dirs[int(root_dirs[0]) + 1]

        # web root
        if sickrage.srCore.srConfig.WEB_ROOT:
            sickrage.srCore.srConfig.WEB_ROOT = sickrage.srCore.srConfig.WEB_ROOT = (
                '/' + sickrage.srCore.srConfig.WEB_ROOT.lstrip('/').strip('/'))

        # api root
        if not sickrage.srCore.srConfig.API_KEY:
            sickrage.srCore.srConfig.API_KEY = generateApiKey()
        self.api_root = r'%s/api/%s' % (sickrage.srCore.srConfig.WEB_ROOT, sickrage.srCore.srConfig.API_KEY)

        # tornado setup
        if sickrage.srCore.srConfig.ENABLE_HTTPS:
            # If either the HTTPS certificate or key do not exist, make some self-signed ones.
            if not (
                        sickrage.srCore.srConfig.HTTPS_CERT and os.path.exists(
                        sickrage.srCore.srConfig.HTTPS_CERT)) or not (
                        sickrage.srCore.srConfig.HTTPS_KEY and os.path.exists(sickrage.srCore.srConfig.HTTPS_KEY)):
                if not create_https_certificates(sickrage.srCore.srConfig.HTTPS_CERT,
                                                 sickrage.srCore.srConfig.HTTPS_KEY):
                    sickrage.srCore.srLogger.info("Unable to create CERT/KEY files, disabling HTTPS")
                    sickrage.srCore.srConfig.ENABLE_HTTPS = False

            if not (os.path.exists(sickrage.srCore.srConfig.HTTPS_CERT) and os.path.exists(
                    sickrage.srCore.srConfig.HTTPS_KEY)):
                sickrage.srCore.srLogger.warning("Disabled HTTPS because of missing CERT and KEY files")
                sickrage.srCore.srConfig.ENABLE_HTTPS = False

        # Load the app
        self.app = Application([],
                               debug=False,
                               autoreload=False,
                               gzip=sickrage.srCore.srConfig.WEB_USE_GZIP,
                               xheaders=sickrage.srCore.srConfig.HANDLE_REVERSE_PROXY,
                               cookie_secret=sickrage.srCore.srConfig.WEB_COOKIE_SECRET,
                               login_url='%s/login/' % sickrage.srCore.srConfig.WEB_ROOT)

        # Main Handlers
        self.app.add_handlers('.*$', [
            # webapi handler
            (r'%s(/?.*)' % self.api_root, ApiHandler),

            # webapi key retrieval
            (r'%s/getkey(/?.*)' % sickrage.srCore.srConfig.WEB_ROOT, KeyHandler),

            # webapi builder redirect
            (r'%s/api/builder' % sickrage.srCore.srConfig.WEB_ROOT, RedirectHandler,
             {"url": sickrage.srCore.srConfig.WEB_ROOT + '/apibuilder/'}),

            # webui login/logout handlers
            (r'%s/login(/?)' % sickrage.srCore.srConfig.WEB_ROOT, LoginHandler),
            (r'%s/logout(/?)' % sickrage.srCore.srConfig.WEB_ROOT, LogoutHandler),

            # webui handlers
        ] + Route.get_routes(sickrage.srCore.srConfig.WEB_ROOT))

        # Web calendar handler (Needed because option Unprotected calendar)
        self.app.add_handlers('.*$', [
            (r'%s/calendar' % sickrage.srCore.srConfig.WEB_ROOT, CalendarHandler),
        ])

        # Static File Handlers
        self.app.add_handlers(".*$", [
            # favicon
            (r'%s/(favicon\.ico)' % sickrage.srCore.srConfig.WEB_ROOT, StaticFileHandler,
             {"path": os.path.join(sickrage.srCore.srConfig.GUI_DIR, 'images/ico/favicon.ico')}),

            # images
            (r'%s.*?/images/(.*)' % sickrage.srCore.srConfig.WEB_ROOT, StaticImageHandler,
             {"path": os.path.join(sickrage.srCore.srConfig.GUI_DIR, 'images')}),

            # css
            (r'%s/css/(.*)' % sickrage.srCore.srConfig.WEB_ROOT, StaticFileHandler,
             {"path": os.path.join(sickrage.srCore.srConfig.GUI_DIR, 'css')}),

            # scss
            (r'%s/scss/(.*)' % sickrage.srCore.srConfig.WEB_ROOT, StaticFileHandler,
             {"path": os.path.join(sickrage.srCore.srConfig.GUI_DIR, 'scss')}),

            # fonts
            (r'%s/fonts/(.*)' % sickrage.srCore.srConfig.WEB_ROOT, StaticFileHandler,
             {"path": os.path.join(sickrage.srCore.srConfig.GUI_DIR, 'fonts')}),

            # javascript
            (r'%s/js/(.*)' % sickrage.srCore.srConfig.WEB_ROOT, StaticFileHandler,
             {"path": os.path.join(sickrage.srCore.srConfig.GUI_DIR, 'js')}),

            # videos
        ] + [(r'%s/videos/(.*)' % sickrage.srCore.srConfig.WEB_ROOT, StaticFileHandler,
              {"path": self.video_root})])

        self.server = HTTPServer(self.app, no_keep_alive=True)

        if sickrage.srCore.srConfig.ENABLE_HTTPS: self.server.ssl_options = {
            "certfile": sickrage.srCore.srConfig.HTTPS_CERT,
            "keyfile": sickrage.srCore.srConfig.HTTPS_KEY
        }

        try:
            self.server.listen(sickrage.srCore.srConfig.WEB_PORT, None)
        except socket.error as e:
            print(e.message)
            raise

        # launch browser window
        if all([not sickrage.NOLAUNCH, sickrage.srCore.srConfig.LAUNCH_BROWSER]):
            threading.Thread(None,
                             lambda: launch_browser(
                                 ('http', 'https')[sickrage.srCore.srConfig.ENABLE_HTTPS],
                                 get_lan_ip(),
                                 sickrage.srCore.srConfig.WEB_PORT
                             )).start()

        # clear mako cache folder
        makocache = os.path.join(sickrage.srCore.srConfig.CACHE_DIR, 'mako')
        if os.path.isdir(makocache):
            shutil.rmtree(makocache)

        sickrage.srCore.srLogger.info("SiCKRAGE :: STARTED")
        sickrage.srCore.srLogger.info("SiCKRAGE :: VERSION:[{}]".format(sickrage.srCore.VERSIONUPDATER.updater.version))
        sickrage.srCore.srLogger.info("SiCKRAGE :: CONFIG:[{}]".format(sickrage.CONFIG_FILE))
        sickrage.srCore.srLogger.info("SiCKRAGE :: URL:[{}://{}:{}/]".format(
            ('http', 'https')[sickrage.srCore.srConfig.ENABLE_HTTPS],
            get_lan_ip(), sickrage.srCore.srConfig.WEB_PORT))

    def shutdown(self):
        if self.started:
            self.server.close_all_connections()
            self.server.stop()
            self.started = False