#!/usr/bin/env python # # This file is part of SickGear. # # SickGear is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # SickGear is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with SickGear. If not, see . # Check needed software dependencies to nudge users to fix their setup from __future__ import print_function from __future__ import with_statement import codecs import datetime import errno import getopt import os import signal import sys import shutil import time import threading import warnings warnings.filterwarnings('ignore', module=r'.*bs4_parser.*', message='.*No parser was explicitly specified.*') warnings.filterwarnings('ignore', module=r'.*Cheetah.*') warnings.filterwarnings('ignore', module=r'.*connectionpool.*', message='.*certificate verification.*') warnings.filterwarnings('ignore', module=r'.*fuzzywuzzy.*') warnings.filterwarnings('ignore', module=r'.*ssl_.*', message='.*SSLContext object.*') warnings.filterwarnings('ignore', module=r'.*zoneinfo.*', message='.*file or directory.*') warnings.filterwarnings('ignore', message='.*deprecated in cryptography.*') versions = [((3, 7, 1), (3, 8, 16)), ((3, 9, 0), (3, 9, 2)), ((3, 9, 4), (3, 9, 16)), ((3, 10, 0), (3, 11, 2))] # inclusive version ranges if not any(list(map(lambda v: v[0] <= sys.version_info[:3] <= v[1], versions))) and not int(os.environ.get('PYT', 0)): print('Python %s.%s.%s detected.' % sys.version_info[:3]) print('Sorry, SickGear requires a Python version %s' % ', '.join(map( lambda r: '%s - %s' % tuple(map(lambda v: str(v).replace(',', '.')[1:-1], r)), versions))) sys.exit(1) sys.path.insert(1, os.path.abspath(os.path.join(os.path.dirname(__file__), 'lib'))) is_win = 'win' == sys.platform[0:3] try: try: py_cache_path = os.path.normpath(os.path.join(os.path.dirname(__file__), '__pycache__')) for pf in ['_cleaner.pyc', '_cleaner.pyo']: cleaner_file = os.path.normpath(os.path.join(os.path.normpath(os.path.dirname(__file__)), pf)) if os.path.isfile(cleaner_file): os.remove(cleaner_file) if os.path.isdir(py_cache_path): shutil.rmtree(py_cache_path) except (BaseException, Exception): pass import _cleaner from sickgear import piper except (BaseException, Exception): pass try: import Cheetah except (BaseException, Exception): print('The Python module Cheetah is required') if is_win: print('(1) However, this first run may have just installed it, so try to simply rerun sickgear.py again') print('(2) If this output is a rerun of (1) then open a command line prompt and manually install using...') else: print('Manually install using...') print('cd ') print('python -m pip install --user -r requirements.txt') print('python sickgear.py') sys.exit(1) # Compatibility fixes for Windows if is_win: codecs.register(lambda name: codecs.lookup('utf-8') if name == 'cp65001' else None) # We only need this for compiling an EXE from multiprocessing import freeze_support from configobj import ConfigObj # noinspection PyPep8Naming from encodingKludge import SYS_ENCODING from exceptions_helper import ex import sickgear from sickgear import db, logger, name_cache, network_timezones from sickgear.event_queue import Events from sickgear.tv import TVShow from sickgear.webserveInit import WebServer from six import integer_types, iteritems throwaway = datetime.datetime.strptime('20110101', '%Y%m%d') rollback_loaded = None for signal_type in [signal.SIGTERM, signal.SIGINT] + ([] if not is_win else [signal.SIGBREAK]): signal.signal(signal_type, lambda signum, void: sickgear.sig_handler(signum=signum, _=void)) class SickGear(object): def __init__(self): # system event callback for shutdown/restart sickgear.events = Events(self.shutdown) # daemon constants self.run_as_daemon = False self.create_pid = False self.pid_file = '' self.run_as_systemd = False self.console_logging = False # webserver constants self.webserver = None self.force_update = False self.forced_port = None self.no_launch = False self.web_options = None self.webhost = None self.start_port = None self.log_dir = None @staticmethod def help_message(): """ print help message for commandline options """ global is_win help_msg = [''] help_msg += ['Usage: %s