示例#1
0
    def start(self):
        self.started = True

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

        # init sentry
        self.init_sentry()

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

        # init core classes
        self.api = API()
        self.config = Config(self.db_type, self.db_prefix, self.db_host,
                             self.db_port, self.db_username, self.db_password)
        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.notification_providers = NotificationProviders()
        self.metadata_providers = MetadataProviders()
        self.search_providers = SearchProviders()
        self.series_providers = SeriesProviders()
        self.log = Logger()
        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()
        self.amqp_client = AMQPClient()

        # 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:
                # remove restore files
                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')))

        # setup databases
        self.main_db.setup()
        self.config.db.setup()
        self.cache_db.setup()

        # load config
        self.config.load()

        # migrate config
        self.config.migrate_config_file(self.config_file)

        # add server id tag to sentry
        sentry_sdk.set_tag('server_id', self.config.general.server_id)

        # add user to sentry
        sentry_sdk.set_user({
            'id': self.config.user.sub_id,
            'username': self.config.user.username,
            'email': self.config.user.email
        })

        # config overrides
        if self.web_port:
            self.config.general.web_port = self.web_port
        if self.web_root:
            self.config.general.web_root = self.web_root

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

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

        # set ssl cert/key filenames
        self.https_cert_file = os.path.abspath(
            os.path.join(self.data_dir, 'server.crt'))
        self.https_key_file = os.path.abspath(
            os.path.join(self.data_dir, 'server.key'))

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

        # start logger
        self.log.start()

        # user agent
        if self.config.general.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.general.default_page not in DefaultHomePage:
            self.config.general.default_page = DefaultHomePage.HOME

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

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

        self.naming_force_folders = check_force_season_folders()

        if self.config.general.nzb_method not in NzbMethod:
            self.config.general.nzb_method = NzbMethod.BLACKHOLE

        if self.config.general.torrent_method not in TorrentMethod:
            self.config.general.torrent_method = TorrentMethod.BLACKHOLE

        if self.config.general.auto_postprocessor_freq < self.min_auto_postprocessor_freq:
            self.config.general.auto_postprocessor_freq = self.min_auto_postprocessor_freq

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

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

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

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

        if self.config.failed_snatches.age < self.min_failed_snatch_age:
            self.config.failed_snatches.age = self.min_failed_snatch_age

        if self.config.general.proper_searcher_interval not in CheckPropersInterval:
            self.config.general.proper_searcher_interval = CheckPropersInterval.DAILY

        if self.config.general.show_update_hour < 0 or self.config.general.show_update_hour > 23:
            self.config.general.show_update_hour = 0

        # add app updater job
        self.scheduler.add_job(
            self.version_updater.task,
            IntervalTrigger(hours=1,
                            start_date=datetime.datetime.now() +
                            datetime.timedelta(minutes=4),
                            timezone='utc'),
            name=self.version_updater.name,
            id=self.version_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.general.show_update_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.general.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.general.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.general.auto_postprocessor_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=self.config.general.proper_searcher_interval.value,
                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.general.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)

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

        # start web server
        self.wserver.start()

        # start scheduler service
        self.scheduler.start()

        # perform server checkup
        IOLoop.current().add_callback(self.server_checkup)

        # load shows
        IOLoop.current().add_callback(self.load_shows)

        # load network timezones
        IOLoop.current().spawn_callback(
            self.tz_updater.update_network_timezones)

        # load search provider urls
        IOLoop.current().spawn_callback(self.search_providers.update_urls)

        # startup message
        IOLoop.current().add_callback(self.startup_message)

        # launch browser
        IOLoop.current().add_callback(self.launch_browser)

        # perform server checkups every hour
        PeriodicCallback(self.server_checkup, 1 * 60 * 60 * 1000).start()

        # perform shutdown trigger check every 5 seconds
        PeriodicCallback(self.shutdown_trigger, 5 * 1000).start()

        # start ioloop
        IOLoop.current().start()
示例#2
0
    def post(self, *args, **kwargs):
        log_nr = self.get_argument('log_nr', '5')
        log_size = self.get_argument('log_size', '1048576')
        web_port = self.get_argument('web_port', None)
        web_ipv6 = self.get_argument('web_ipv6', None)
        web_host = self.get_argument('web_host', None)
        trash_remove_show = self.get_argument('trash_remove_show', None)
        trash_rotate_logs = self.get_argument('trash_rotate_logs', None)
        update_frequency = self.get_argument('update_frequency', None)
        skip_removed_files = self.get_argument('skip_removed_files', None)
        series_provider_default_language = self.get_argument(
            'series_provider_default_language', 'en')
        ep_default_deleted_status = self.get_argument(
            'ep_default_deleted_status', None)
        launch_browser = self.get_argument('launch_browser', None)
        show_update_hour = self.get_argument('show_update_hour', '3')
        api_key = self.get_argument('api_key', None)
        series_provider_default = self.get_argument('series_provider_default',
                                                    None)
        timezone_display = self.get_argument('timezone_display', None)
        cpu_preset = self.get_argument('cpu_preset', 'NORMAL')
        version_notify = self.get_argument('version_notify', None)
        enable_https = self.get_argument('enable_https', None)
        https_cert = self.get_argument('https_cert', None)
        https_key = self.get_argument('https_key', None)
        handle_reverse_proxy = self.get_argument('handle_reverse_proxy', None)
        sort_article = self.get_argument('sort_article', None)
        auto_update = self.get_argument('auto_update', None)
        notify_on_update = self.get_argument('notify_on_update', None)
        backup_on_update = self.get_argument('backup_on_update', None)
        proxy_setting = self.get_argument('proxy_setting', None)
        proxy_series_providers = self.get_argument('proxy_series_providers',
                                                   None)
        anon_redirect = self.get_argument('anon_redirect', None)
        git_path = self.get_argument('git_path', None)
        pip3_path = self.get_argument('pip3_path', None)
        calendar_unprotected = self.get_argument('calendar_unprotected', None)
        calendar_icons = self.get_argument('calendar_icons', None)
        debug = self.get_argument('debug', None)
        ssl_verify = self.get_argument('ssl_verify', None)
        no_restart = self.get_argument('no_restart', None)
        coming_eps_missed_range = self.get_argument('coming_eps_missed_range',
                                                    None)
        filter_row = self.get_argument('filter_row', None)
        fuzzy_dating = self.get_argument('fuzzy_dating', None)
        trim_zero = self.get_argument('trim_zero', None)
        date_preset = self.get_argument('date_preset', None)
        time_preset = self.get_argument('time_preset', None)
        series_provider_timeout = self.get_argument('series_provider_timeout',
                                                    None)
        download_url = self.get_argument('download_url', None)
        theme_name = self.get_argument('theme_name', None)
        default_page = self.get_argument('default_page', None)
        gui_language = self.get_argument('gui_language', None)
        display_all_seasons = self.get_argument('display_all_seasons', None)
        show_update_stale = self.get_argument('show_update_stale', None)
        notify_on_login = self.get_argument('notify_on_login', None)
        allowed_video_file_exts = self.get_argument('allowed_video_file_exts',
                                                    '')
        enable_upnp = self.get_argument('enable_upnp', None)
        strip_special_file_bits = self.get_argument('strip_special_file_bits',
                                                    None)
        max_queue_workers = self.get_argument('max_queue_workers', None)
        web_root = self.get_argument('web_root', '')
        ip_whitelist_localhost_enabled = self.get_argument(
            'ip_whitelist_localhost_enabled', None)
        ip_whitelist_enabled = self.get_argument('ip_whitelist_enabled', None)
        ip_whitelist = self.get_argument('ip_whitelist', '')
        web_auth_method = self.get_argument('web_auth_method', '')
        web_username = self.get_argument('web_username', '')
        web_password = self.get_argument('web_password', '')
        enable_sickrage_api = self.get_argument('enable_sickrage_api', None)

        results = []

        change_gui_lang(gui_language)
        change_show_update_hour(show_update_hour)
        change_version_notify(checkbox_to_value(version_notify))

        # Debug
        sickrage.app.config.general.debug = sickrage.app.debug = checkbox_to_value(
            debug)
        sickrage.app.log.set_level()

        # Misc
        sickrage.app.config.general.enable_upnp = checkbox_to_value(
            enable_upnp)
        sickrage.app.config.general.download_url = download_url
        sickrage.app.config.general.series_provider_default_language = series_provider_default_language
        sickrage.app.config.general.ep_default_deleted_status = EpisodeStatus[
            ep_default_deleted_status]
        sickrage.app.config.general.skip_removed_files = checkbox_to_value(
            skip_removed_files)
        sickrage.app.config.general.launch_browser = checkbox_to_value(
            launch_browser)
        sickrage.app.config.general.auto_update = checkbox_to_value(
            auto_update)
        sickrage.app.config.general.notify_on_update = checkbox_to_value(
            notify_on_update)
        sickrage.app.config.general.backup_on_update = checkbox_to_value(
            backup_on_update)
        sickrage.app.config.general.notify_on_login = checkbox_to_value(
            notify_on_login)
        sickrage.app.config.general.show_update_stale = checkbox_to_value(
            show_update_stale)
        sickrage.app.config.general.log_nr = int(log_nr)
        sickrage.app.config.general.log_size = int(log_size)

        sickrage.app.config.general.trash_remove_show = checkbox_to_value(
            trash_remove_show)
        sickrage.app.config.general.trash_rotate_logs = checkbox_to_value(
            trash_rotate_logs)
        sickrage.app.config.general.launch_browser = checkbox_to_value(
            launch_browser)
        sickrage.app.config.general.sort_article = checkbox_to_value(
            sort_article)
        sickrage.app.config.general.cpu_preset = CpuPreset[cpu_preset]
        sickrage.app.config.general.anon_redirect = anon_redirect
        sickrage.app.config.general.proxy_setting = proxy_setting
        sickrage.app.config.general.proxy_series_providers = checkbox_to_value(
            proxy_series_providers)
        sickrage.app.config.general.git_reset = 1
        sickrage.app.config.general.git_path = git_path
        sickrage.app.config.general.pip3_path = pip3_path
        sickrage.app.config.general.calendar_unprotected = checkbox_to_value(
            calendar_unprotected)
        sickrage.app.config.general.calendar_icons = checkbox_to_value(
            calendar_icons)
        sickrage.app.config.general.no_restart = checkbox_to_value(no_restart)

        sickrage.app.config.general.ssl_verify = checkbox_to_value(ssl_verify)
        sickrage.app.config.gui.coming_eps_missed_range = try_int(
            coming_eps_missed_range, 7)
        sickrage.app.config.general.display_all_seasons = checkbox_to_value(
            display_all_seasons)

        sickrage.app.config.general.web_port = int(web_port)
        sickrage.app.config.general.web_ipv6 = checkbox_to_value(web_ipv6)

        sickrage.app.config.gui.filter_row = checkbox_to_value(filter_row)
        sickrage.app.config.gui.fuzzy_dating = checkbox_to_value(fuzzy_dating)
        sickrage.app.config.gui.trim_zero = checkbox_to_value(trim_zero)

        sickrage.app.config.general.allowed_video_file_exts = ','.join(
            [x.lower() for x in allowed_video_file_exts.split(',')])

        sickrage.app.config.general.strip_special_file_bits = checkbox_to_value(
            strip_special_file_bits)

        sickrage.app.config.general.web_root = web_root

        sickrage.app.config.general.ip_whitelist_enabled = checkbox_to_value(
            ip_whitelist_enabled)
        sickrage.app.config.general.ip_whitelist_localhost_enabled = checkbox_to_value(
            ip_whitelist_localhost_enabled)
        sickrage.app.config.general.ip_whitelist = ip_whitelist

        if web_auth_method == 'sso_auth':
            auth_method_changed = not sickrage.app.config.general.sso_auth_enabled
            sickrage.app.config.general.sso_auth_enabled = True
            sickrage.app.config.general.local_auth_enabled = False
        else:
            auth_method_changed = not sickrage.app.config.general.local_auth_enabled
            sickrage.app.config.general.sso_auth_enabled = False
            sickrage.app.config.general.local_auth_enabled = True
            sickrage.app.config.user.username = web_username
            sickrage.app.config.user.password = web_password

        sickrage.app.config.general.enable_sickrage_api = checkbox_to_value(
            enable_sickrage_api)

        # change_web_external_port(web_external_port)

        if date_preset:
            sickrage.app.config.gui.date_preset = date_preset

        if series_provider_default:
            sickrage.app.config.general.series_provider_default = SeriesProviderID[
                series_provider_default]

        if series_provider_timeout:
            sickrage.app.config.general.series_provider_timeout = try_int(
                series_provider_timeout)

        if time_preset:
            sickrage.app.config.gui.time_preset_w_seconds = time_preset
            sickrage.app.config.gui.time_preset = sickrage.app.config.gui.time_preset_w_seconds.replace(
                ":%S", "")

        sickrage.app.config.gui.timezone_display = TimezoneDisplay[
            timezone_display]

        sickrage.app.config.general.api_v1_key = api_key

        sickrage.app.config.general.enable_https = checkbox_to_value(
            enable_https)

        # if not change_https_cert(https_cert):
        #     results += ["Unable to create directory " + os.path.normpath(https_cert) + ", https cert directory not changed."]
        #
        # if not change_https_key(https_key):
        #     results += ["Unable to create directory " + os.path.normpath(https_key) + ", https key directory not changed."]

        sickrage.app.config.general.handle_reverse_proxy = checkbox_to_value(
            handle_reverse_proxy)

        sickrage.app.config.gui.theme_name = UITheme[theme_name]

        sickrage.app.config.general.default_page = DefaultHomePage[
            default_page]

        sickrage.app.config.general.max_queue_workers = try_int(
            max_queue_workers)

        sickrage.app.config.save()

        if auth_method_changed:
            return self.redirect('/logout')

        if len(results) > 0:
            [sickrage.app.log.error(x) for x in results]
            sickrage.app.alerts.error(_('Error(s) Saving Configuration'),
                                      '<br>\n'.join(results))
        else:
            sickrage.app.alerts.message(
                _('[GENERAL] Configuration Saved to Database'))

        return self.redirect("/config/general/")