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()
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/")