#!/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 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, 8, 0), (3, 8, 16)), ((3, 9, 0), (3, 9, 2)), ((3, 9, 4), (3, 9, 16)), ((3, 10, 0), (3, 11, 3))] # 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)): major, minor, micro = sys.version_info[:3] print('Python %s.%s.%s detected.' % (major, minor, micro)) 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 CT3 (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