mirror of
https://github.com/Tautulli/Tautulli.git
synced 2025-03-12 04:35:40 -07:00
First code for independent notifications (not linked to PlexWatch). New notifications panel in Settings (many types still untested). Standardise the parameters sent to current activity. Remove notifiers we cannot use. Styling fixes for sync tables.
221 lines
7.2 KiB
Python
Executable File
221 lines
7.2 KiB
Python
Executable File
#!/usr/bin/env python
|
|
# This file is part of PlexPy.
|
|
#
|
|
# PlexPy 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.
|
|
#
|
|
# PlexPy 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 PlexPy. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import os
|
|
import sys
|
|
|
|
# Ensure lib added to path, before any other imports
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'lib/'))
|
|
|
|
from plexpy import webstart, logger
|
|
|
|
import locale
|
|
import time
|
|
import signal
|
|
import argparse
|
|
import plexpy
|
|
|
|
# Register signals, such as CTRL + C
|
|
signal.signal(signal.SIGINT, plexpy.sig_handler)
|
|
signal.signal(signal.SIGTERM, plexpy.sig_handler)
|
|
|
|
|
|
def main():
|
|
"""
|
|
PlexPy application entry point. Parses arguments, setups encoding and
|
|
initializes the application.
|
|
"""
|
|
|
|
# Fixed paths to PlexPy
|
|
if hasattr(sys, 'frozen'):
|
|
plexpy.FULL_PATH = os.path.abspath(sys.executable)
|
|
else:
|
|
plexpy.FULL_PATH = os.path.abspath(__file__)
|
|
|
|
plexpy.PROG_DIR = os.path.dirname(plexpy.FULL_PATH)
|
|
plexpy.ARGS = sys.argv[1:]
|
|
|
|
# From sickbeard
|
|
plexpy.SYS_PLATFORM = sys.platform
|
|
plexpy.SYS_ENCODING = None
|
|
|
|
try:
|
|
locale.setlocale(locale.LC_ALL, "")
|
|
plexpy.SYS_ENCODING = locale.getpreferredencoding()
|
|
except (locale.Error, IOError):
|
|
pass
|
|
|
|
# for OSes that are poorly configured I'll just force UTF-8
|
|
if not plexpy.SYS_ENCODING or plexpy.SYS_ENCODING in ('ANSI_X3.4-1968', 'US-ASCII', 'ASCII'):
|
|
plexpy.SYS_ENCODING = 'UTF-8'
|
|
|
|
# Set up and gather command line arguments
|
|
parser = argparse.ArgumentParser(
|
|
description='Python frontend for PlexWatch.')
|
|
|
|
parser.add_argument(
|
|
'-v', '--verbose', action='store_true', help='Increase console logging verbosity')
|
|
parser.add_argument(
|
|
'-q', '--quiet', action='store_true', help='Turn off console logging')
|
|
parser.add_argument(
|
|
'-d', '--daemon', action='store_true', help='Run as a daemon')
|
|
parser.add_argument(
|
|
'-p', '--port', type=int, help='Force PlexPy to run on a specified port')
|
|
parser.add_argument(
|
|
'--datadir', help='Specify a directory where to store your data files')
|
|
parser.add_argument('--config', help='Specify a config file to use')
|
|
parser.add_argument('--nolaunch', action='store_true',
|
|
help='Prevent browser from launching on startup')
|
|
parser.add_argument(
|
|
'--pidfile', help='Create a pid file (only relevant when running as a daemon)')
|
|
|
|
args = parser.parse_args()
|
|
|
|
if args.verbose:
|
|
plexpy.VERBOSE = True
|
|
if args.quiet:
|
|
plexpy.QUIET = True
|
|
|
|
# Do an intial setup of the logger.
|
|
logger.initLogger(console=not plexpy.QUIET, log_dir=False,
|
|
verbose=plexpy.VERBOSE)
|
|
|
|
if args.daemon:
|
|
if sys.platform == 'win32':
|
|
sys.stderr.write(
|
|
"Daemonizing not supported under Windows, starting normally\n")
|
|
else:
|
|
plexpy.DAEMON = True
|
|
plexpy.QUIET = True
|
|
|
|
if args.pidfile:
|
|
plexpy.PIDFILE = str(args.pidfile)
|
|
|
|
# If the pidfile already exists, plexpy may still be running, so
|
|
# exit
|
|
if os.path.exists(plexpy.PIDFILE):
|
|
raise SystemExit("PID file '%s' already exists. Exiting." %
|
|
plexpy.PIDFILE)
|
|
|
|
# The pidfile is only useful in daemon mode, make sure we can write the
|
|
# file properly
|
|
if plexpy.DAEMON:
|
|
plexpy.CREATEPID = True
|
|
|
|
try:
|
|
with open(plexpy.PIDFILE, 'w') as fp:
|
|
fp.write("pid\n")
|
|
except IOError as e:
|
|
raise SystemExit("Unable to write PID file: %s", e)
|
|
else:
|
|
logger.warn("Not running in daemon mode. PID file creation " \
|
|
"disabled.")
|
|
|
|
# Determine which data directory and config file to use
|
|
if args.datadir:
|
|
plexpy.DATA_DIR = args.datadir
|
|
else:
|
|
plexpy.DATA_DIR = plexpy.PROG_DIR
|
|
|
|
if args.config:
|
|
config_file = args.config
|
|
else:
|
|
config_file = os.path.join(plexpy.DATA_DIR, 'config.ini')
|
|
|
|
# Try to create the DATA_DIR if it doesn't exist
|
|
if not os.path.exists(plexpy.DATA_DIR):
|
|
try:
|
|
os.makedirs(plexpy.DATA_DIR)
|
|
except OSError:
|
|
raise SystemExit(
|
|
'Could not create data directory: ' + plexpy.DATA_DIR + '. Exiting....')
|
|
|
|
# Make sure the DATA_DIR is writeable
|
|
if not os.access(plexpy.DATA_DIR, os.W_OK):
|
|
raise SystemExit(
|
|
'Cannot write to the data directory: ' + plexpy.DATA_DIR + '. Exiting...')
|
|
|
|
# Put the database in the DATA_DIR
|
|
plexpy.DB_FILE = os.path.join(plexpy.DATA_DIR, 'plexpy.db')
|
|
|
|
# Read config and start logging
|
|
plexpy.initialize(config_file)
|
|
|
|
if plexpy.DAEMON:
|
|
plexpy.daemonize()
|
|
|
|
# Force the http port if neccessary
|
|
if args.port:
|
|
http_port = args.port
|
|
logger.info('Using forced web server port: %i', http_port)
|
|
else:
|
|
http_port = int(plexpy.CONFIG.HTTP_PORT)
|
|
|
|
# Check if pyOpenSSL is installed. It is required for certificate generation
|
|
# and for CherryPy.
|
|
if plexpy.CONFIG.ENABLE_HTTPS:
|
|
try:
|
|
import OpenSSL
|
|
except ImportError:
|
|
logger.warn("The pyOpenSSL module is missing. Install this " \
|
|
"module to enable HTTPS. HTTPS will be disabled.")
|
|
plexpy.CONFIG.ENABLE_HTTPS = False
|
|
|
|
# Try to start the server. Will exit here is address is already in use.
|
|
web_config = {
|
|
'http_port': http_port,
|
|
'http_host': plexpy.CONFIG.HTTP_HOST,
|
|
'http_root': plexpy.CONFIG.HTTP_ROOT,
|
|
'http_proxy': plexpy.CONFIG.HTTP_PROXY,
|
|
'enable_https': plexpy.CONFIG.ENABLE_HTTPS,
|
|
'https_cert': plexpy.CONFIG.HTTPS_CERT,
|
|
'https_key': plexpy.CONFIG.HTTPS_KEY,
|
|
'http_username': plexpy.CONFIG.HTTP_USERNAME,
|
|
'http_password': plexpy.CONFIG.HTTP_PASSWORD,
|
|
}
|
|
webstart.initialize(web_config)
|
|
|
|
# Start the background threads
|
|
plexpy.start()
|
|
|
|
# Open webbrowser
|
|
if plexpy.CONFIG.LAUNCH_BROWSER and not args.nolaunch:
|
|
plexpy.launch_browser(plexpy.CONFIG.HTTP_HOST, http_port,
|
|
plexpy.CONFIG.HTTP_ROOT)
|
|
|
|
# Wait endlessy for a signal to happen
|
|
while True:
|
|
if not plexpy.SIGNAL:
|
|
try:
|
|
time.sleep(1)
|
|
except KeyboardInterrupt:
|
|
plexpy.SIGNAL = 'shutdown'
|
|
else:
|
|
logger.info('Received signal: %s', plexpy.SIGNAL)
|
|
|
|
if plexpy.SIGNAL == 'shutdown':
|
|
plexpy.shutdown()
|
|
elif plexpy.SIGNAL == 'restart':
|
|
plexpy.shutdown(restart=True)
|
|
else:
|
|
plexpy.shutdown(restart=True, update=True)
|
|
|
|
plexpy.SIGNAL = None
|
|
|
|
# Call main()
|
|
if __name__ == "__main__":
|
|
main()
|