Пример #1
0
    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()
Пример #2
0
    def _find_internal_ip_on_device_network(self, upnp_dev):
        lan_ip = get_lan_ip()
        parsed_url = urlparse(upnp_dev.location)
        upnp_dev_net = ipaddress.ip_network(parsed_url.hostname + '/24', strict=False)

        if ipaddress.ip_address(unicode(lan_ip)) in upnp_dev_net:
            return lan_ip
        return None
Пример #3
0
    def _find_internal_ip_on_device_network(self, upnp_dev):
        lan_ip = get_lan_ip()
        parsed_url = urlparse(upnp_dev.location)
        upnp_dev_net = ipaddress.ip_network(parsed_url.hostname + '/24',
                                            strict=False)

        if ipaddress.ip_address(unicode(lan_ip)) in upnp_dev_net:
            return lan_ip
        return None
Пример #4
0
def setUp_test_web_server():
    sickrage.WEB_SERVER = SRWebServer(**{
        'port': 8081,
        'host': get_lan_ip(),
        'data_root': sickrage.DATA_DIR,
        'gui_root': sickrage.GUI_DIR,
        'web_root': sickrage.WEB_ROOT,
        'log_dir': sickrage.WEB_LOG or sickrage.LOG_DIR,
        'username': sickrage.WEB_USERNAME,
        'password': sickrage.WEB_PASSWORD,
        'enable_https': sickrage.ENABLE_HTTPS,
        'handle_reverse_proxy': sickrage.HANDLE_REVERSE_PROXY,
        'https_cert': os.path.join(sickrage.ROOT_DIR, sickrage.HTTPS_CERT),
        'https_key': os.path.join(sickrage.ROOT_DIR, sickrage.HTTPS_KEY),
        'daemonize': sickrage.DAEMONIZE,
        'pidfile': sickrage.PIDFILE,
        'stop_timeout': 3,
        'nolaunch': sickrage.WEB_NOLAUNCH
    })

    threading.Thread(None, sickrage.WEB_SERVER.start).start()
Пример #5
0
def setUp_test_web_server():
    sickrage.WEB_SERVER = SRWebServer(
        **{
            'port': 8081,
            'host': get_lan_ip(),
            'data_root': sickrage.DATA_DIR,
            'gui_root': sickrage.GUI_DIR,
            'web_root': sickrage.WEB_ROOT,
            'log_dir': sickrage.WEB_LOG or sickrage.LOG_DIR,
            'username': sickrage.WEB_USERNAME,
            'password': sickrage.WEB_PASSWORD,
            'enable_https': sickrage.ENABLE_HTTPS,
            'handle_reverse_proxy': sickrage.HANDLE_REVERSE_PROXY,
            'https_cert': os.path.join(sickrage.ROOT_DIR, sickrage.HTTPS_CERT),
            'https_key': os.path.join(sickrage.ROOT_DIR, sickrage.HTTPS_KEY),
            'daemonize': sickrage.DAEMONIZE,
            'pidfile': sickrage.PIDFILE,
            'stop_timeout': 3,
            'nolaunch': sickrage.WEB_NOLAUNCH
        })

    threading.Thread(None, sickrage.WEB_SERVER.start).start()
Пример #6
0
def setUp_test_web_server():
    sickrage.WEB_SERVER = SRWebServer(
        **{
            "port": 8081,
            "host": get_lan_ip(),
            "data_root": sickrage.DATA_DIR,
            "gui_root": sickrage.GUI_DIR,
            "web_root": sickrage.WEB_ROOT,
            "log_dir": sickrage.WEB_LOG or sickrage.LOG_DIR,
            "username": sickrage.WEB_USERNAME,
            "password": sickrage.WEB_PASSWORD,
            "enable_https": sickrage.ENABLE_HTTPS,
            "handle_reverse_proxy": sickrage.HANDLE_REVERSE_PROXY,
            "https_cert": os.path.join(sickrage.ROOT_DIR, sickrage.HTTPS_CERT),
            "https_key": os.path.join(sickrage.ROOT_DIR, sickrage.HTTPS_KEY),
            "daemonize": sickrage.DAEMONIZE,
            "pidfile": sickrage.PIDFILE,
            "stop_timeout": 3,
            "nolaunch": sickrage.WEB_NOLAUNCH,
        }
    )

    threading.Thread(None, sickrage.WEB_SERVER.start).start()
Пример #7
0
    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()
Пример #8
0
    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))
Пример #9
0
    def start(self):
        self.started = True

        # thread name
        threading.currentThread().setName('CORE')

        # event loop policy that allows loop creation on any thread.
        asyncio.set_event_loop_policy(AnyThreadEventLoopPolicy())

        # scheduler
        self.scheduler = BackgroundScheduler({'apscheduler.timezone': 'UTC'})

        # init core classes
        self.api = API()
        self.main_db = MainDB(self.db_type, self.db_prefix, self.db_host, self.db_port, self.db_username, self.db_password)
        self.cache_db = CacheDB(self.db_type, self.db_prefix, self.db_host, self.db_port, self.db_username, self.db_password)
        self.notifier_providers = NotifierProviders()
        self.metadata_providers = MetadataProviders()
        self.search_providers = SearchProviders()
        self.log = Logger()
        self.config = Config()
        self.alerts = Notifications()
        self.wserver = WebServer()
        self.show_queue = ShowQueue()
        self.search_queue = SearchQueue()
        self.postprocessor_queue = PostProcessorQueue()
        self.version_updater = VersionUpdater()
        self.show_updater = ShowUpdater()
        self.tz_updater = TimeZoneUpdater()
        self.rsscache_updater = RSSCacheUpdater()
        self.daily_searcher = DailySearcher()
        self.failed_snatch_searcher = FailedSnatchSearcher()
        self.backlog_searcher = BacklogSearcher()
        self.proper_searcher = ProperSearcher()
        self.trakt_searcher = TraktSearcher()
        self.subtitle_searcher = SubtitleSearcher()
        self.auto_postprocessor = AutoPostProcessor()
        self.upnp_client = UPNPClient()
        self.announcements = Announcements()

        # authorization sso client
        self.auth_server = AuthServer()

        # check available space
        try:
            self.log.info("Performing disk space checks")
            total_space, available_space = get_free_space(self.data_dir)
            if available_space < 100:
                self.log.warning('Shutting down as SiCKRAGE needs some space to work. You\'ll get corrupted data otherwise. Only %sMB left', available_space)
                return
        except Exception:
            self.log.error('Failed getting disk space: %s', traceback.format_exc())

        # check if we need to perform a restore first
        if os.path.exists(os.path.abspath(os.path.join(self.data_dir, 'restore'))):
            self.log.info('Performing restore of backup files')
            success = restore_app_data(os.path.abspath(os.path.join(self.data_dir, 'restore')), self.data_dir)
            self.log.info("Restoring SiCKRAGE backup: %s!" % ("FAILED", "SUCCESSFUL")[success])
            if success:
                # self.main_db = MainDB(self.db_type, self.db_prefix, self.db_host, self.db_port, self.db_username, self.db_password)
                # self.cache_db = CacheDB(self.db_type, self.db_prefix, self.db_host, self.db_port, self.db_username, self.db_password)
                shutil.rmtree(os.path.abspath(os.path.join(self.data_dir, 'restore')), ignore_errors=True)

        # migrate old database file names to new ones
        if os.path.isfile(os.path.abspath(os.path.join(self.data_dir, 'sickbeard.db'))):
            if os.path.isfile(os.path.join(self.data_dir, 'sickrage.db')):
                helpers.move_file(os.path.join(self.data_dir, 'sickrage.db'),
                                  os.path.join(self.data_dir, '{}.bak-{}'
                                               .format('sickrage.db',
                                                       datetime.datetime.now().strftime(
                                                           '%Y%m%d_%H%M%S'))))

            helpers.move_file(os.path.abspath(os.path.join(self.data_dir, 'sickbeard.db')),
                              os.path.abspath(os.path.join(self.data_dir, 'sickrage.db')))

        # init encryption public and private keys
        encryption.initialize()

        # load config
        self.config.load()

        # set language
        self.config.change_gui_lang(self.config.gui_lang)

        # set socket timeout
        socket.setdefaulttimeout(self.config.socket_timeout)

        # setup logger settings
        self.log.logSize = self.config.log_size
        self.log.logNr = self.config.log_nr
        self.log.logFile = os.path.join(self.data_dir, 'logs', 'sickrage.log')
        self.log.debugLogging = self.config.debug
        self.log.consoleLogging = not self.quiet

        # start logger
        self.log.start()

        # perform database startup actions
        for db in [self.main_db, self.cache_db]:
            # perform integrity check
            self.log.info("Performing integrity check on {} database".format(db.name))
            db.integrity_check()

            # migrate database
            self.log.info("Performing migrations on {} database".format(db.name))
            db.migrate()

            # upgrade database
            self.log.info("Performing upgrades on {} database".format(db.name))
            db.upgrade()

            # cleanup
            self.log.info("Performing cleanup on {} database".format(db.name))
            db.cleanup()

        # user agent
        if self.config.random_user_agent:
            self.user_agent = UserAgent().random

        uses_netloc.append('scgi')
        FancyURLopener.version = self.user_agent

        # set torrent client web url
        torrent_webui_url(True)

        if self.config.default_page not in ('schedule', 'history', 'IRC'):
            self.config.default_page = 'home'

        # attempt to help prevent users from breaking links by using a bad url
        if not self.config.anon_redirect.endswith('?'):
            self.config.anon_redirect = ''

        if not re.match(r'\d+\|[^|]+(?:\|[^|]+)*', self.config.root_dirs):
            self.config.root_dirs = ''

        self.config.naming_force_folders = check_force_season_folders()

        if self.config.nzb_method not in ('blackhole', 'sabnzbd', 'nzbget'):
            self.config.nzb_method = 'blackhole'

        if self.config.torrent_method not in ('blackhole', 'utorrent', 'transmission', 'deluge', 'deluged',
                                              'download_station', 'rtorrent', 'qbittorrent', 'mlnet', 'putio'):
            self.config.torrent_method = 'blackhole'

        if self.config.autopostprocessor_freq < self.config.min_autopostprocessor_freq:
            self.config.autopostprocessor_freq = self.config.min_autopostprocessor_freq

        if self.config.daily_searcher_freq < self.config.min_daily_searcher_freq:
            self.config.daily_searcher_freq = self.config.min_daily_searcher_freq

        if self.config.backlog_searcher_freq < self.config.min_backlog_searcher_freq:
            self.config.backlog_searcher_freq = self.config.min_backlog_searcher_freq

        if self.config.version_updater_freq < self.config.min_version_updater_freq:
            self.config.version_updater_freq = self.config.min_version_updater_freq

        if self.config.subtitle_searcher_freq < self.config.min_subtitle_searcher_freq:
            self.config.subtitle_searcher_freq = self.config.min_subtitle_searcher_freq

        if self.config.failed_snatch_age < self.config.min_failed_snatch_age:
            self.config.failed_snatch_age = self.config.min_failed_snatch_age

        if self.config.proper_searcher_interval not in ('15m', '45m', '90m', '4h', 'daily'):
            self.config.proper_searcher_interval = 'daily'

        if self.config.showupdate_hour < 0 or self.config.showupdate_hour > 23:
            self.config.showupdate_hour = 0

        # add version checker job
        self.scheduler.add_job(
            self.version_updater.task,
            IntervalTrigger(
                hours=self.config.version_updater_freq,
                timezone='utc'
            ),
            name=self.version_updater.name,
            id=self.version_updater.name
        )

        # add network timezones updater job
        self.scheduler.add_job(
            self.tz_updater.task,
            IntervalTrigger(
                days=1,
                timezone='utc'
            ),
            name=self.tz_updater.name,
            id=self.tz_updater.name
        )

        # add show updater job
        self.scheduler.add_job(
            self.show_updater.task,
            IntervalTrigger(
                days=1,
                start_date=datetime.datetime.now().replace(hour=self.config.showupdate_hour),
                timezone='utc'
            ),
            name=self.show_updater.name,
            id=self.show_updater.name
        )

        # add rss cache updater job
        self.scheduler.add_job(
            self.rsscache_updater.task,
            IntervalTrigger(
                minutes=15,
                timezone='utc'
            ),
            name=self.rsscache_updater.name,
            id=self.rsscache_updater.name
        )

        # add daily search job
        self.scheduler.add_job(
            self.daily_searcher.task,
            IntervalTrigger(
                minutes=self.config.daily_searcher_freq,
                start_date=datetime.datetime.now() + datetime.timedelta(minutes=4),
                timezone='utc'
            ),
            name=self.daily_searcher.name,
            id=self.daily_searcher.name
        )

        # add failed snatch search job
        self.scheduler.add_job(
            self.failed_snatch_searcher.task,
            IntervalTrigger(
                hours=1,
                start_date=datetime.datetime.now() + datetime.timedelta(minutes=4),
                timezone='utc'
            ),
            name=self.failed_snatch_searcher.name,
            id=self.failed_snatch_searcher.name
        )

        # add backlog search job
        self.scheduler.add_job(
            self.backlog_searcher.task,
            IntervalTrigger(
                minutes=self.config.backlog_searcher_freq,
                start_date=datetime.datetime.now() + datetime.timedelta(minutes=30),
                timezone='utc'
            ),
            name=self.backlog_searcher.name,
            id=self.backlog_searcher.name
        )

        # add auto-postprocessing job
        self.scheduler.add_job(
            self.auto_postprocessor.task,
            IntervalTrigger(
                minutes=self.config.autopostprocessor_freq,
                timezone='utc'
            ),
            name=self.auto_postprocessor.name,
            id=self.auto_postprocessor.name
        )

        # add find proper job
        self.scheduler.add_job(
            self.proper_searcher.task,
            IntervalTrigger(
                minutes={
                    '15m': 15,
                    '45m': 45,
                    '90m': 90,
                    '4h': 4 * 60,
                    'daily': 24 * 60
                }[self.config.proper_searcher_interval],
                timezone='utc'
            ),
            name=self.proper_searcher.name,
            id=self.proper_searcher.name
        )

        # add trakt.tv checker job
        self.scheduler.add_job(
            self.trakt_searcher.task,
            IntervalTrigger(
                hours=1,
                timezone='utc'
            ),
            name=self.trakt_searcher.name,
            id=self.trakt_searcher.name
        )

        # add subtitles finder job
        self.scheduler.add_job(
            self.subtitle_searcher.task,
            IntervalTrigger(
                hours=self.config.subtitle_searcher_freq,
                timezone='utc'
            ),
            name=self.subtitle_searcher.name,
            id=self.subtitle_searcher.name
        )

        # add upnp client job
        self.scheduler.add_job(
            self.upnp_client.task,
            IntervalTrigger(
                seconds=self.upnp_client._nat_portmap_lifetime,
                timezone='utc'
            ),
            name=self.upnp_client.name,
            id=self.upnp_client.name
        )

        # add announcements job
        self.scheduler.add_job(
            self.announcements.task,
            IntervalTrigger(
                minutes=15,
                timezone='utc'
            ),
            name=self.announcements.name,
            id=self.announcements.name
        )

        # add provider URL update job
        self.scheduler.add_job(
            self.search_providers.task,
            IntervalTrigger(
                hours=1,
                timezone='utc'
            ),
            name=self.search_providers.name,
            id=self.search_providers.name
        )

        # start queues
        self.search_queue.start_worker(self.config.max_queue_workers)
        self.show_queue.start_worker(self.config.max_queue_workers)
        self.postprocessor_queue.start_worker(self.config.max_queue_workers)

        # start web server
        self.wserver.start()

        # fire off jobs now
        self.scheduler.get_job(self.version_updater.name).modify(next_run_time=datetime.datetime.utcnow())
        self.scheduler.get_job(self.tz_updater.name).modify(next_run_time=datetime.datetime.utcnow())
        self.scheduler.get_job(self.announcements.name).modify(next_run_time=datetime.datetime.utcnow())
        self.scheduler.get_job(self.search_providers.name).modify(next_run_time=datetime.datetime.utcnow())

        # start scheduler service
        self.scheduler.start()

        # load shows
        self.scheduler.add_job(self.load_shows)

        # launch browser window
        if all([not sickrage.app.no_launch, sickrage.app.config.launch_browser]):
            self.scheduler.add_job(launch_browser, args=[('http', 'https')[sickrage.app.config.enable_https],
                                                         sickrage.app.config.web_host, sickrage.app.config.web_port])

        self.log.info("SiCKRAGE :: STARTED")
        self.log.info("SiCKRAGE :: APP VERSION:[{}]".format(sickrage.version()))
        self.log.info("SiCKRAGE :: CONFIG VERSION:[v{}]".format(self.config.config_version))
        self.log.info("SiCKRAGE :: DATABASE VERSION:[v{}]".format(self.main_db.version))
        self.log.info("SiCKRAGE :: DATABASE TYPE:[{}]".format(self.db_type))
        self.log.info("SiCKRAGE :: URL:[{}://{}:{}/{}]".format(('http', 'https')[self.config.enable_https],
                                                               (self.config.web_host, get_lan_ip())[self.config.web_host == '0.0.0.0'],
                                                               self.config.web_port,
                                                               self.config.web_root))
Пример #10
0
    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))