Example #1
0
def saveAndShutdown(restart=False):

    halt()

    saveAll()

    logger.log(u"Killing cherrypy")
    cherrypy.engine.exit()

    if CREATEPID:
        logger.log(u"Removing pidfile " + str(PIDFILE))
        os.remove(PIDFILE)
    '''
    if restart:
        install_type = versionCheckScheduler.action.install_type

        popen_list = [sys.executable, MY_FULLNAME]

        if popen_list:
            popen_list += MY_ARGS
            if '--nolaunch' not in popen_list:
                popen_list += ['--nolaunch']
            logger.log(u"Restarting Sick Beard with " + str(popen_list))
            subprocess.Popen(popen_list, cwd=os.getcwd())
    '''
    os._exit(0)
Example #2
0
def saveAll():

    global showList

    # save config
    logger.log(u"Saving config file to disk")
    save_config()
Example #3
0
def create_https_certificates(ssl_cert, ssl_key):
    """
    Create self-signed HTTPS certificares and store in paths 'ssl_cert' and 'ssl_key'
    """
    try:
        from OpenSSL import crypto
        from lib.certgen import createKeyPair, createCertRequest, createCertificate, TYPE_RSA, serial
    except:
        logger.log(u"pyopenssl module missing, please install for https access", logger.WARNING)
        return False

    # Create the CA Certificate
    cakey = createKeyPair(TYPE_RSA, 1024)
    careq = createCertRequest(cakey, CN='Certificate Authority')
    cacert = createCertificate(careq, (careq, cakey), serial, (0, 60*60*24*365*10)) # ten years

    cname = 'Metaweb'
    pkey = createKeyPair(TYPE_RSA, 1024)
    req = createCertRequest(pkey, CN=cname)
    cert = createCertificate(req, (cacert, cakey), serial, (0, 60*60*24*365*10)) # ten years

    # Save the key and certificate to disk
    try:
        open(ssl_key, 'w').write(crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey))
        open(ssl_cert, 'w').write(crypto.dump_certificate(crypto.FILETYPE_PEM, cert))
    except:
        logger.log(u"Error creating SSL key and certificate", logger.ERROR)
        return False

    return True
Example #4
0
 def saveGeneral(self, admin_user=None, general_user=None):
     if len(results) > 0:
         for x in results:
             logger.log(x, logger.ERROR)
         ui.notifications.error('Error(s) Saving Configuration',
                     '<br />\n'.join(results))
     else:
         ui.notifications.message('Configuration Saved', ek.ek(os.path.join, sickbeard.CONFIG_FILE) )
Example #5
0
def initialize(consoleLogging=True):

    with INIT_LOCK:

        global LOG_DIR, WEB_PORT, WEB_LOG, WEB_ROOT, WEB_USERNAME, WEB_PASSWORD, WEB_HOST, WEB_IPV6, \
                ENABLE_HTTPS, HTTPS_CERT, HTTPS_KEY, GIT_PATH, showUpdateScheduler, __INITIALIZED__

        if __INITIALIZED__:
            return False

        socket.setdefaulttimeout(SOCKET_TIMEOUT)

        CheckSection('General')

        LOG_DIR = check_setting_str(CFG, 'General', 'log_dir', 'Logs')
        if not helpers.makeDir(LOG_DIR):
            logger.log(u"!!! No log folder, logging to screen only!", logger.ERROR)

        try:
            WEB_PORT = check_setting_int(CFG, 'General', 'web_port', 8081)
        except:
            WEB_PORT = 8081

        if WEB_PORT < 21 or WEB_PORT > 65535:
            WEB_PORT = 8081

        WEB_HOST = check_setting_str(CFG, 'General', 'web_host', '0.0.0.0')
        WEB_IPV6 = bool(check_setting_int(CFG, 'General', 'web_ipv6', 0))
        WEB_ROOT = check_setting_str(CFG, 'General', 'web_root', '').rstrip("/")
        WEB_LOG = bool(check_setting_int(CFG, 'General', 'web_log', 0))
        WEB_USERNAME = check_setting_str(CFG, 'General', 'web_username', '')
        WEB_PASSWORD = check_setting_str(CFG, 'General', 'web_password', '')

        ENABLE_HTTPS = bool(check_setting_int(CFG, 'General', 'enable_https', 0))

        HTTPS_CERT = check_setting_str(CFG, 'General', 'https_cert', 'server.crt')
        HTTPS_KEY = check_setting_str(CFG, 'General', 'https_key', 'server.key')

        ROOT_DIRS = check_setting_str(CFG, 'General', 'root_dirs', '')
        if not re.match(r'\d+\|[^|]+(?:\|[^|]+)*', ROOT_DIRS):
            ROOT_DIRS = ''

        GIT_PATH = check_setting_str(CFG, 'General', 'git_path', '')

        logger.mw_log_instance.initLogging(consoleLogging=consoleLogging)

        mcconfig.mc_config.getConfig()
        WEB_USERNAME = mcconfig.mc_config.config['web_admin_user']
        WEB_PASSWORD = mcconfig.mc_config.config['web_admin_pwd']
        #mcconfig.mc_config.saveConfig()

        #versionCheckScheduler = scheduler.Scheduler(versionChecker.CheckVersion(),
        #                                             cycleTime=datetime.timedelta(hours=12),
        #                                             threadName="CHECKVERSION",
        #                                             runImmediately=True)

        __INITIALIZED__ = True
        return True
Example #6
0
	def saveConfig(self):
		try:
			with open("/tmp/test", 'w') as f:
				for name, value in self.config.items():
					line = name + '="' + value + '"\n' 
					f.write(line)
			return True
		except BaseException as e:
			logger.log(u"Error saving config: %s" % e)
			return False
Example #7
0
	def getConfig(self):
		try:
			with open("/tmp/mc-config", 'r') as f:
				tmp = f.read().split('\n')
			pairs = []
			for i in tmp:
				pairs.append(i.split('='))
				#conf[pair[0]] = pair[1].strip('"')
			pairs.pop()
			self.config = {k: v.strip('"') for k, v in pairs}
		except BaseException as e:
			logger.log(u"Error getting config: %s" % e)
Example #8
0
def restart(soft=True):

    if soft:
        halt()
        saveAll()
        #logger.log(u"Restarting cherrypy")
        #cherrypy.engine.restart()
        logger.log(u"Re-initializing all data")
        initialize()

    else:
        saveAndShutdown(restart=True)
Example #9
0
def check_setting_int(config, cfg_name, item_name, def_val):
    try:
        my_val = int(config[cfg_name][item_name])
    except:
        my_val = def_val
        try:
            config[cfg_name][item_name] = my_val
        except:
            config[cfg_name] = {}
            config[cfg_name][item_name] = my_val
    logger.log(item_name + " -> " + str(my_val), logger.DEBUG)
    return my_val
Example #10
0
def fixStupidEncodings(x, silent=False):
    if type(x) == str:
        try:
            return x.decode('UTF-8')
        except UnicodeDecodeError:
            logger.log(u"Unable to decode value: " + repr(x), logger.ERROR)
            return None
    elif type(x) == unicode:
        return x
    else:
        logger.log(u"Unknown value passed in, ignoring it: " + str(type(x)) + " (" + repr(x) + ":" + repr(type(x)) + ")", logger.DEBUG if silent else logger.ERROR)
        return None

    return None
Example #11
0
def rename_file(old_path, new_name):

    old_path_list = ek.ek(os.path.split, old_path)
    old_file_ext = os.path.splitext(old_path_list[1])[1]

    new_path = ek.ek(os.path.join, old_path_list[0], sanitizeFileName(new_name) + old_file_ext)

    logger.log(u"Renaming from " + old_path + " to " + new_path)

    try:
        ek.ek(os.rename, old_path, new_path)
    except (OSError, IOError), e:
        logger.log(u"Failed renaming " + old_path + " to " + new_path + ": " + ex(e), logger.ERROR)
        return False
Example #12
0
def change_HTTPS_KEY(https_key):

    if https_key == '':
        metaweb.HTTPS_KEY = ''
        return True

    if os.path.normpath(metaweb.HTTPS_KEY) != os.path.normpath(https_key):
        if helpers.makeDir(os.path.dirname(os.path.abspath(https_key))):
            metaweb.HTTPS_KEY = os.path.normpath(https_key)
            logger.log(u"Changed https key path to " + https_key)
        else:
            return False

    return True
Example #13
0
def change_HTTPS_CERT(https_cert):

    if https_cert == '':
        metaweb.HTTPS_CERT = ''
        return True

    if os.path.normpath(metaweb.HTTPS_CERT) != os.path.normpath(https_cert):
        if helpers.makeDir(os.path.dirname(os.path.abspath(https_cert))):
            metaweb.HTTPS_CERT = os.path.normpath(https_cert)
            logger.log(u"Changed https cert path to " + https_cert)
        else:
            return False

    return True
Example #14
0
def check_setting_str(config, cfg_name, item_name, def_val, log=True):
    try:
        my_val = config[cfg_name][item_name]
    except:
        my_val = def_val
        try:
            config[cfg_name][item_name] = my_val
        except:
            config[cfg_name] = {}
            config[cfg_name][item_name] = my_val

    if log:
        logger.log(item_name + " -> " + my_val, logger.DEBUG)
    else:
        logger.log(item_name + " -> ******", logger.DEBUG)
    return my_val
Example #15
0
def change_LOG_DIR(log_dir):

    if os.path.normpath(metaweb.LOG_DIR) != os.path.normpath(log_dir):
        if helpers.makeDir(log_dir):
            metaweb.LOG_DIR = os.path.normpath(log_dir)
            logger.mw_log_instance.initLogging()
            logger.log(u"Initialized new log file in " + log_dir)

            cherry_log = os.path.join(metaweb.LOG_DIR, "cherrypy.log")
            cherrypy.config.update({'log.access_file': cherry_log})

            logger.log(u"Changed cherry log file to " + cherry_log)

        else:
            return False

    return True
Example #16
0
    def http_error_401_hander(status, message, traceback, version):
        """ Custom handler for 401 error """
        if status != "401 Unauthorized":
            logger.log(u"CherryPy caught an error: %s %s" % (status, message), logger.ERROR)
            logger.log(traceback, logger.DEBUG)
        return r"""
<html>
    <head>
        <title>%s</title>
    </head>
    <body>
        <br/>
        <font color="#0000FF">Error %s: You need to provide a valid username and password.</font>
    </body>
</html>
""" % (
            "Access denied",
            status,
        )
Example #17
0
def fixSetGroupID(childPath):
    if os.name == 'nt' or os.name == 'ce':
        return

    parentPath = ek.ek(os.path.dirname, childPath)
    parentStat = os.stat(parentPath)
    parentMode = stat.S_IMODE(parentStat[stat.ST_MODE])

    if parentMode & stat.S_ISGID:
        parentGID = parentStat[stat.ST_GID]
        childGID = os.stat(childPath)[stat.ST_GID]

        if childGID == parentGID:
            return

        try:
            ek.ek(os.chown, childPath, -1, parentGID)
            logger.log(u"Respecting the set-group-ID bit on the parent directory for %s" % (childPath), logger.DEBUG)
        except OSError:
            logger.log(u"Failed to respect the set-group-ID bit on the parent directory for %s (setting group ID %i)" % (childPath, parentGID), logger.ERROR)
Example #18
0
def halt ():

    global __INITIALIZED__, started

    with INIT_LOCK:

        if __INITIALIZED__:

            logger.log(u"Aborting all threads")

            # abort all the threads

            #versionCheckScheduler.abort = True
            #logger.log(u"Waiting for the VERSIONCHECKER thread to exit")
            #try:
            #    versionCheckScheduler.thread.join(10)
            #except:
            #    pass

            __INITIALIZED__ = False
Example #19
0
def chmodAsParent(childPath):
    if os.name == 'nt' or os.name == 'ce':
        return

    parentPath = ek.ek(os.path.dirname, childPath)

    if not parentPath:
        logger.log(u"No parent path provided in "+childPath+", unable to get permissions from it", logger.DEBUG)
        return

    parentMode = stat.S_IMODE(os.stat(parentPath)[stat.ST_MODE])

    if ek.ek(os.path.isfile, childPath):
        childMode = fileBitFilter(parentMode)
    else:
        childMode = parentMode

    try:
        ek.ek(os.chmod, childPath, childMode)
        logger.log(u"Setting permissions for %s to %o as parent directory has %o" % (childPath, childMode, parentMode), logger.DEBUG)
    except OSError:
        logger.log(u"Failed to set permission for %s to %o" % (childPath, childMode), logger.ERROR)
Example #20
0
def initWebServer(options={}):
    options.setdefault("port", 8081)
    options.setdefault("host", "0.0.0.0")
    options.setdefault("log_dir", None)
    options.setdefault("username", "")
    options.setdefault("password", "")
    options.setdefault("web_root", "/")
    assert isinstance(options["port"], int)
    assert "data_root" in options

    def http_error_401_hander(status, message, traceback, version):
        """ Custom handler for 401 error """
        if status != "401 Unauthorized":
            logger.log(u"CherryPy caught an error: %s %s" % (status, message), logger.ERROR)
            logger.log(traceback, logger.DEBUG)
        return r"""
<html>
    <head>
        <title>%s</title>
    </head>
    <body>
        <br/>
        <font color="#0000FF">Error %s: You need to provide a valid username and password.</font>
    </body>
</html>
""" % (
            "Access denied",
            status,
        )

    def http_error_404_hander(status, message, traceback, version):
        """ Custom handler for 404 error, redirect back to main page """
        return (
            r"""
<html>
    <head>
        <title>404</title>
        <script type="text/javascript" charset="utf-8">
          <!--
          location.href = "%s"
          //-->
        </script>
    </head>
    <body>
        <br/>
    </body>
</html>
"""
            % "/"
        )

    # cherrypy setup
    enable_https = options["enable_https"]
    https_cert = options["https_cert"]
    https_key = options["https_key"]

    if enable_https:
        # If either the HTTPS certificate or key do not exist, make some self-signed ones.
        if not (https_cert and os.path.exists(https_cert)) or not (https_key and os.path.exists(https_key)):
            if not create_https_certificates(https_cert, https_key):
                logger.log(u"Unable to create cert/key files, disabling HTTPS")
                metaweb.ENABLE_HTTPS = False
                enable_https = False

        if not (os.path.exists(https_cert) and os.path.exists(https_key)):
            logger.log(u"Disabled HTTPS because of missing CERT and KEY files", logger.WARNING)
            metaweb.ENABLE_HTTPS = False
            enable_https = False

    options_dict = {
        "server.socket_port": options["port"],
        "server.socket_host": options["host"],
        "log.screen": False,
        "error_page.401": http_error_401_hander,
        #'error_page.404':     http_error_404_hander,
    }

    if enable_https:
        options_dict["server.ssl_certificate"] = https_cert
        options_dict["server.ssl_private_key"] = https_key
        protocol = "https"
    else:
        protocol = "http"

    logger.log(u"Starting MetaWeb on " + protocol + "://" + str(options["host"]) + ":" + str(options["port"]) + "/")
    cherrypy.config.update(options_dict)

    # setup cherrypy logging
    if options["log_dir"] and os.path.isdir(options["log_dir"]):
        cherrypy.config.update({"log.access_file": os.path.join(options["log_dir"], "cherrypy.log")})
        logger.log("Using %s for cherrypy log" % cherrypy.config["log.access_file"])

    conf = {
        "/": {"tools.staticdir.root": options["data_root"], "tools.encode.on": True, "tools.encode.encoding": "utf-8"},
        "/images": {"tools.staticdir.on": True, "tools.staticdir.dir": "images"},
        "/js": {"tools.staticdir.on": True, "tools.staticdir.dir": "js"},
        "/css": {"tools.staticdir.on": True, "tools.staticdir.dir": "css"},
    }
    app = cherrypy.tree.mount(WebInterface(), options["web_root"], conf)

    # auth
    if options["username"] != "" and options["password"] != "":
        checkpassword = cherrypy.lib.auth_basic.checkpassword_dict({options["username"]: options["password"]})
        app.merge(
            {
                "/": {
                    "tools.auth_basic.on": True,
                    "tools.auth_basic.realm": "MetaWeb",
                    "tools.auth_basic.checkpassword": checkpassword,
                },
                "/api": {"tools.auth_basic.on": False},
                "/api/builder": {
                    "tools.auth_basic.on": True,
                    "tools.auth_basic.realm": "MetaWeb",
                    "tools.auth_basic.checkpassword": checkpassword,
                },
            }
        )

    cherrypy.server.start()
    cherrypy.server.wait()
Example #21
0
def invoke_command(to_call, *args, **kwargs):
    global invoked_command
    def delegate():
        to_call(*args, **kwargs)
    invoked_command = delegate
    logger.log(u"Placed invoked command: " + repr(invoked_command) + " for " + repr(to_call) + " with " + repr(args) + " and " + repr(kwargs), logger.DEBUG)
Example #22
0
    # Make the child a session-leader by detaching from the terminal
    try:
        pid = os.fork()
        if pid != 0:
            sys.exit(0)
    except OSError, e:
        raise RuntimeError("2nd fork failed: %s [%d]" %
                   (e.strerror, e.errno))

    dev_null = file('/dev/null', 'r')
    os.dup2(dev_null.fileno(), sys.stdin.fileno())

    if metaweb.CREATEPID:
        pid = str(os.getpid())
        logger.log(u"Writing PID " + pid + " to " + str(metaweb.PIDFILE))
        file(metaweb.PIDFILE, 'w').write("%s\n" % pid)

def main():
    # do some preliminary stuff
    metaweb.MY_FULLNAME = os.path.normpath(os.path.abspath(__file__))
    metaweb.MY_NAME = os.path.basename(metaweb.MY_FULLNAME)
    metaweb.PROG_DIR = os.path.dirname(metaweb.MY_FULLNAME)
    metaweb.DATA_DIR = metaweb.PROG_DIR
    metaweb.MY_ARGS = sys.argv[1:]
    metaweb.CREATEPID = False
    metaweb.DAEMON = False
    # need console logging
    consoleLogging = (not hasattr(sys, "frozen")) or (metaweb.MY_NAME.lower().find('-console') > 0)
    # rename the main thread
    threading.currentThread().name = "MAIN"
Example #23
0
def sig_handler(signum=None, frame=None):
    if type(signum) != type(None):
        logger.log(u"Signal %i caught, saving and exiting..." % int(signum))
        saveAndShutdown()
Example #24
0
def main():
    # do some preliminary stuff
    metaweb.MY_FULLNAME = os.path.normpath(os.path.abspath(__file__))
    metaweb.MY_NAME = os.path.basename(metaweb.MY_FULLNAME)
    metaweb.PROG_DIR = os.path.dirname(metaweb.MY_FULLNAME)
    metaweb.DATA_DIR = metaweb.PROG_DIR
    metaweb.MY_ARGS = sys.argv[1:]
    metaweb.CREATEPID = False
    metaweb.DAEMON = False
    # need console logging
    consoleLogging = (not hasattr(sys, "frozen")) or (metaweb.MY_NAME.lower().find('-console') > 0)
    # rename the main thread
    threading.currentThread().name = "MAIN"

    try:
        opts, args = getopt.getopt(sys.argv[1:], "qdp::", ['quiet', 'daemon', 'port=', 'pidfile=', 'config=', 'datadir='])
    except getopt.GetoptError:
        print "Available options: --quiet, --daemon, --port, --pidfile, --config, --datadir"
        sys.exit()

    forcedPort = None

    for o, a in opts:
        # for now we'll just silence the logging
        if o in ('-q', '--quiet'):
            consoleLogging = False

        # use a different port
        if o in ('-p', '--port'):
            forcedPort = int(a)

        # Run as a daemon
        if o in ('-d', '--daemon'):
            consoleLogging = False
            metaweb.DAEMON = True

        # config file
        if o in ('--config',):
            metaweb.CONFIG_FILE = os.path.abspath(a)

        # datadir
        if o in ('--datadir',):
            metaweb.DATA_DIR = os.path.abspath(a)

        # write a pidfile if requested
        if o in ('--pidfile',):
            metaweb.PIDFILE = str(a)

            # if the pidfile already exists, metaweb may still be running, so exit
            if os.path.exists(metaweb.PIDFILE):
                sys.exit("PID file " + metaweb.PIDFILE + " already exists. Exiting.")

            # a pidfile is only useful in daemon mode
            # also, test to make sure we can write the file properly
            if metaweb.DAEMON:
                metaweb.CREATEPID = True
                try:
                    file(metaweb.PIDFILE, 'w').write("pid\n")
                except IOError, e:
                    raise SystemExit("Unable to write PID file: %s [%d]" % (e.strerror, e.errno))
            else:
                logger.log(u"Not running in daemon mode. PID file creation disabled.")