示例#1
0
def backup():
    logger.debug("Starting backup")
    backup_folder = os.path.join(nzbhydra.getBasePath(), "backup")
    logger.debug("Using backup folder %s" % backup_folder)
    if not os.path.exists(backup_folder):
        logger.debug("Backup folder %s doesn't exist. Creating it." %
                     backup_folder)
        os.mkdir(backup_folder)
    backup_file = os.path.join(
        backup_folder,
        "nzbhydra-backup-%s.zip" % arrow.now().format("YYYY-MM-DD-HH-mm"))
    logger.debug("Writing backup to file %s" % backup_file)
    logger.debug("Compressing ZIP file" if compression == zipfile.
                 ZIP_DEFLATED else "zlib not found. Not compressing ZIP file")
    zf = zipfile.ZipFile(backup_file, mode="w")

    try:
        zf.write(nzbhydra.configFile, compress_type=compression)
        zf.write(nzbhydra.databaseFile, compress_type=compression)
        zf.close()
        logger.info("Successfully backed up database and settings to %s" %
                    backup_file)
        return backup_file
    except Exception as e:
        logger.exception("Error creating backup file", e)
        return None
示例#2
0
def backup():
    from nzbhydra import update
    logger.debug("Starting backup")
    backup_folder = os.path.join(nzbhydra.getBasePath(), "backup")
    logger.debug("Using backup folder %s" % backup_folder)
    if not os.path.exists(backup_folder):
        logger.debug("Backup folder %s doesn't exist. Creating it." % backup_folder)
        os.mkdir(backup_folder)
    backup_file = os.path.join(backup_folder, "nzbhydra-backup-%s.zip" % arrow.now().format("YYYY-MM-DD-HH-mm"))
    logger.debug("Writing backup to file %s" % backup_file)
    logger.debug("Compressing ZIP file" if compression == zipfile.ZIP_DEFLATED else "zlib not found. Not compressing ZIP file")
    zf = zipfile.ZipFile(backup_file, mode="w")
    fileInfo = json.dumps({"configFile": os.path.basename(nzbhydra.configFile),
                           "databaseFile": os.path.basename(nzbhydra.databaseFile),
                           "version": update.get_current_version()[1]})
    
    try:
        zf.write(nzbhydra.configFile, arcname=os.path.basename(nzbhydra.configFile), compress_type=compression)
        zf.write(nzbhydra.databaseFile, arcname=os.path.basename(nzbhydra.databaseFile), compress_type=compression)
        zf.writestr("hydraBackupInfo.txt", fileInfo, compress_type=compression)
        zf.close()
        logger.info("Successfully backed up database and settings to %s" % backup_file)
        return backup_file
    except Exception as e:
        logger.exception("Error creating backup file")
        return None
示例#3
0
def getDebuggingInfos():
    logger.debug("Starting creation of debugging infos ZIP")
    ac = json.dumps(config.getAnonymizedConfig(), indent=4)
    debug_folder = os.path.join(nzbhydra.getBasePath(), "debug")
    logger.debug("Using debug folder %s" % debug_folder)
    if not os.path.exists(debug_folder):
        logger.debug("Debug folder %s doesn't exist. Creating it." % debug_folder)
        os.mkdir(debug_folder)
    debuginfo_file = os.path.join(debug_folder, "nzbhydra-debuginfo-%s.zip" % arrow.now().format("YYYY-MM-DD-HH-mm"))
    logger.debug("Writing debugging info to file %s" % debuginfo_file)
    logger.debug("Using compression for ZIP file" if compression == zipfile.ZIP_DEFLATED else "zlib not found. Not compressing ZIP file")

    al_file = os.path.join(debug_folder, "logfile.txt")
    log.getAnonymizedLogFile(config.getSettingsToHide(), al_file)

    ac_file = os.path.join(debug_folder, "settings.txt")
    logger.debug("Writing settings to temp file %s" % ac_file)
    with codecs.open(ac_file, "w", "utf-8") as textfile:
        textfile.write(ac)

    logger.debug("Writing ZIP file")
    zf = zipfile.ZipFile(debuginfo_file, mode="w")
    try:
        zf.write(filename=al_file, arcname=os.path.basename(al_file), compress_type=compression)
        zf.write(filename=ac_file, arcname=os.path.basename(ac_file), compress_type=compression)
        
        zf.close()
        os.remove(ac_file)
        os.remove(al_file)
        logger.info("Successfully wrote debugging infos to file %s" % debuginfo_file)
        return debuginfo_file
    except Exception as e:
        logger.exception("Error creating debug infos")
        return None
示例#4
0
def getBackupFilenames():
    backup_folder = os.path.join(nzbhydra.getBasePath(), "backup")
    if not os.path.exists(backup_folder):
        logger.debug("Backup folder %s does not exist. No backups found" % backup_folder)
        return []
    logger.debug("Listing backups in folder %s" % backup_folder)
    files = os.listdir(backup_folder)
    backupFiles = []
    for filename in files:
        if not filename.lower().endswith(".zip"):
            continue
        f = os.path.join(backup_folder, filename)
        fileAge = arrow.get(os.path.getmtime(f))
        backupFiles.append({"filename": filename, "age": fileAge.humanize(), "sortable": fileAge.timestamp})
    backupFiles.sort(key=lambda x: x["sortable"], reverse=True)
    logger.debug("Found %d backup files" % len(backupFiles))
    return backupFiles
示例#5
0
def getDebuggingInfos():
    logger.debug("Starting creation of debugging infos ZIP")
    ac = json.dumps(config.getAnonymizedConfig(), indent=4)
    debug_folder = os.path.join(nzbhydra.getBasePath(), "debug")
    logger.debug("Using debug folder %s" % debug_folder)
    if not os.path.exists(debug_folder):
        logger.debug("Debug folder %s doesn't exist. Creating it." %
                     debug_folder)
        os.mkdir(debug_folder)
    debuginfo_file = os.path.join(
        debug_folder,
        "nzbhydra-debuginfo-%s.zip" % arrow.now().format("YYYY-MM-DD-HH-mm"))
    logger.debug("Writing debugging info to file %s" % debuginfo_file)
    logger.debug("Compressing ZIP file" if compression == zipfile.
                 ZIP_DEFLATED else "zlib not found. Not compressing ZIP file")

    al = log.getAnonymizedLogFile(config.getSettingsToHide())
    al_file = os.path.join(debug_folder, "logfile.txt")
    logger.debug("Writing log to temp file %s" % al_file)
    with codecs.open(al_file, "w", "utf-8") as textfile:
        textfile.write(al)

    ac_file = os.path.join(debug_folder, "settings.txt")
    logger.debug("Writing settings to temp file %s" % ac_file)
    with codecs.open(ac_file, "w", "utf-8") as textfile:
        textfile.write(ac)

    zf = zipfile.ZipFile(debuginfo_file, mode="w")
    try:
        zf.write(filename=al_file,
                 arcname=os.path.basename(al_file),
                 compress_type=compression)
        zf.write(filename=ac_file,
                 arcname=os.path.basename(ac_file),
                 compress_type=compression)

        zf.close()
        os.remove(ac_file)
        os.remove(al_file)
        logger.info("Successfully wrote debugging infos to file %s" %
                    debuginfo_file)
        return debuginfo_file
    except Exception as e:
        logger.exception("Error creating debug infos", e)
        return None
示例#6
0
def getBackupFilenames():
    backup_folder = os.path.join(nzbhydra.getBasePath(), "backup")
    if not os.path.exists(backup_folder):
        logger.debug("Backup folder %s does not exist. No backups found" %
                     backup_folder)
        return []
    logger.debug("Listing backups in folder %s" % backup_folder)
    files = os.listdir(backup_folder)
    backupFiles = []
    for filename in files:
        if not filename.lower().endswith(".zip"):
            continue
        f = os.path.join(backup_folder, filename)
        backupFiles.append({
            "filename": filename,
            "age": arrow.get(os.path.getctime(f)).humanize()
        })
    backupFiles.reverse()
    logger.debug("Found %d backup files" % len(backupFiles))
    return backupFiles
示例#7
0
def backup():
    from nzbhydra import update
    logger.debug("Starting backup")
    backup_folder = os.path.join(nzbhydra.getBasePath(), "backup")
    logger.debug("Using backup folder %s" % backup_folder)
    if not os.path.exists(backup_folder):
        logger.debug("Backup folder %s doesn't exist. Creating it." %
                     backup_folder)
        os.mkdir(backup_folder)
    backup_file = os.path.join(
        backup_folder,
        "nzbhydra-backup-%s.zip" % arrow.now().format("YYYY-MM-DD-HH-mm"))
    logger.debug("Writing backup to file %s" % backup_file)
    logger.debug("Compressing ZIP file" if compression == zipfile.
                 ZIP_DEFLATED else "zlib not found. Not compressing ZIP file")
    zf = zipfile.ZipFile(backup_file, mode="w")
    fileInfo = json.dumps({
        "configFile":
        os.path.basename(nzbhydra.configFile),
        "databaseFile":
        os.path.basename(nzbhydra.databaseFile),
        "version":
        update.get_current_version()[1]
    })

    try:
        zf.write(nzbhydra.configFile,
                 arcname=os.path.basename(nzbhydra.configFile),
                 compress_type=compression)
        zf.write(nzbhydra.databaseFile,
                 arcname=os.path.basename(nzbhydra.databaseFile),
                 compress_type=compression)
        zf.writestr("hydraBackupInfo.txt", fileInfo, compress_type=compression)
        zf.close()
        logger.info("Successfully backed up database and settings to %s" %
                    backup_file)
        return backup_file
    except Exception as e:
        logger.exception("Error creating backup file")
        return None
示例#8
0
def getBackupFilenames():
    backup_folder = os.path.join(nzbhydra.getBasePath(), "backup")
    if not os.path.exists(backup_folder):
        logger.debug("Backup folder %s does not exist. No backups found" %
                     backup_folder)
        return []
    logger.debug("Listing backups in folder %s" % backup_folder)
    files = os.listdir(backup_folder)
    backupFiles = []
    for filename in files:
        if not filename.lower().endswith(".zip"):
            continue
        f = os.path.join(backup_folder, filename)
        fileAge = arrow.get(os.path.getmtime(f))
        backupFiles.append({
            "filename": filename,
            "age": fileAge.humanize(),
            "sortable": fileAge.timestamp
        })
    backupFiles.sort(key=lambda x: x["sortable"], reverse=True)
    logger.debug("Found %d backup files" % len(backupFiles))
    return backupFiles
示例#9
0
def restoreFromBackupData(zipData):
    logger.info("Attempting to restore data from backup ZIP")
    try:
        zf = zipfile.ZipFile(zipData, "r", compression=compression)
    except zipfile.BadZipfile:
        logger.error("File is not a ZIP")
        return "File is not a ZIP", 500
    containedFiles = zf.namelist()
    if "hydraBackupInfo.txt" not in containedFiles:
        noBackupInfoError = "Unable to restore from backup file because it doesn't contain a file called 'hydraBackupInfo.txt'. Either the ZIP is no NZB Hydra backup file or it was created before version 0.2.148."
        logger.error(noBackupInfoError)
        return noBackupInfoError, 500
    try:
        tempFolder = os.path.join(nzbhydra.getBasePath(), "temp")
        if os.path.exists(tempFolder):
            logger.info("Deleting old temp folder")
            shutil.rmtree(tempFolder)
        logger.info("Creating new temp folder %s" % tempFolder)
        os.mkdir(tempFolder)
    except Exception as e:
        logger.exception("Error while (re)creating temp folder")
        return "An error occured while (re)creating the temp folder: %s" % e, 500

    try:
        backupInfoString = zf.read("hydraBackupInfo.txt")
    except KeyError:
        infoMissingTest = "Unable to find hydraBackupInfo.txt. Please note that only backup files created version 0.2.148ff are supported"
        logger.error(infoMissingTest)
        return infoMissingTest
    try:
        backupInfo = json.loads(backupInfoString)
        logger.info("Found backup info in archive: %s" % backupInfoString)
        configFileName = backupInfo["configFile"]
        databaseFileName = backupInfo["databaseFile"]
        logger.info("Extracting backup data to temp folder %s" % tempFolder)
        zf.extract(configFileName, tempFolder)
        zf.extract(databaseFileName, tempFolder)
    except Exception as e:
        logger.exception("Error while extracting backup ZIP")
        return "An error occured while extracting the data from the backup ZIP: %s" % e, 500

    try:
        logger.info("Shutting down database")
        dbStopped = database.db.stop()
        if dbStopped:
            database.db.close()
    except Exception as e:
        logger.exception("Error while shutting down database")
        try:
            database.db.start()
        except Exception as e:
            return "Unable to recover from database error: %s. You might need to restart" % e, 500
        return "An error occured while shutting down the database: %s" % e, 500

    databaseFileRestored = False
    databaseFileTempBackup = None
    configFileTempBackup = None
    try:
        logger.info("Starting to restore database file to %s" %
                    nzbhydra.databaseFile)
        databaseFileTempBackup = nzbhydra.databaseFile + ".tempBackup"
        logger.info("Renaming database file %s to temporary backup file %s" %
                    (nzbhydra.databaseFile, databaseFileTempBackup))
        shutil.move(nzbhydra.databaseFile, databaseFileTempBackup)
        databaseTempFile = os.path.join(tempFolder,
                                        os.path.basename(databaseFileName))
        logger.info("Replacing database file %s with extracted file %s" %
                    (nzbhydra.databaseFile, databaseTempFile))
        shutil.move(databaseTempFile, nzbhydra.databaseFile)
        databaseFileRestored = True

        logger.info("Starting to restore settings file to %s" %
                    nzbhydra.configFile)
        configFileTempBackup = nzbhydra.configFile + ".tempBackup"
        logger.info("Renaming config file %s to temporary backup file %s" %
                    (nzbhydra.configFile, configFileTempBackup))
        shutil.move(nzbhydra.configFile, configFileTempBackup)
        configTempFile = os.path.join(tempFolder,
                                      os.path.basename(configFileName))
        logger.info("Replacing config file %s with extracted file %s" %
                    (nzbhydra.configFile, configTempFile))
        shutil.move(configTempFile, nzbhydra.configFile)

        logger.info("Restoration completed successfully.")
    except Exception as e:
        logger.exception("Error while restoring files")
        logger.info("Restoring original state")
        if databaseFileRestored:
            if databaseFileTempBackup is not None:
                logger.info(
                    "Moving temporary database backup file %s back to %s" %
                    (databaseFileTempBackup, nzbhydra.databaseFile))
                if os.path.exists(nzbhydra.databaseFile):
                    os.unlink(nzbhydra.databaseFile)
                shutil.move(databaseFileTempBackup, nzbhydra.databaseFile)
            else:
                logger.error(
                    "Unable to bring back database file to state before restore"
                )
        if configFileTempBackup is not None:
            logger.info("Moving temporary config backup file %s back to %s" %
                        (configFileTempBackup, nzbhydra.configFile))
            if os.path.exists(nzbhydra.configFile):
                os.unlink(nzbhydra.configFile)
            shutil.move(configFileTempBackup, nzbhydra.configFile)
        else:
            logger.error(
                "Unable to bring back config file to state before restore")
        return "Error while restoring files: %s. Original state was restored." % e, 500
    finally:
        try:
            if databaseFileTempBackup is not None and os.path.exists(
                    databaseFileTempBackup):
                logger.info("Deleting temporary backup of database file %s" %
                            databaseFileTempBackup)
                os.unlink(databaseFileTempBackup)
            if configFileTempBackup is not None and os.path.exists(
                    configFileTempBackup):
                logger.info("Deleting temporary backup of config file %s" %
                            configFileTempBackup)
                os.unlink(configFileTempBackup)
            logger.info("Deleting temp folder %s" % tempFolder)
            shutil.rmtree(tempFolder)
        except Exception as e:
            logger.error("Error while cleaning up")

    return "OK"
示例#10
0
def getBackupFileByFilename(filename):
    backup_folder = os.path.join(nzbhydra.getBasePath(), "backup")
    backup_file = os.path.join(backup_folder, filename)
    return backup_file
示例#11
0
def getBackupFileByFilename(filename):
    backup_folder = os.path.join(nzbhydra.getBasePath(), "backup")
    backup_file = os.path.join(backup_folder, filename)
    return backup_file
示例#12
0
def run(arguments):
    arguments.config = arguments.config if os.path.isabs(arguments.config) else os.path.join(nzbhydra.getBasePath(), arguments.config)
    arguments.database = arguments.database if os.path.isabs(arguments.database) else os.path.join(nzbhydra.getBasePath(), arguments.database)
    nzbhydra.configFile = settings_file = arguments.config
    nzbhydra.databaseFile = database_file = arguments.database

    logger.notice("Loading settings from {}".format(settings_file))
    try:
        config.load(settings_file)
        config.save(settings_file)  # Write any new settings back to the file
        log.setup_custom_logger(arguments.logfile, arguments.quiet)
    except Exception:
        print("An error occured during migrating the old config. Sorry about that...: ")
        traceback.print_exc(file=sys.stdout)
        print("Trying to log messages from migration...")
        config.logLogMessages()
        os._exit(-5)

    try:
        logger.info("Started")

        if arguments.daemon:
            logger.info("Daemonizing...")
            daemonize(arguments.pidfile)

        config.logLogMessages()

        if arguments.clearloganddb:
            logger.warning("Deleting log file and database now as requested")
            try:
                logger.warning("Deleting database file %s" % database_file)
                os.unlink(database_file)
            except Exception as e:
                logger.error("Unable to close or delete log file: %s" % e)

            try:
                handler = logger.handlers[1] if len(logger.handlers) == 2 else logger.handlers[0]
                filename = handler.stream.name

                if filename and os.path.exists(filename):
                    logger.warn("Deleting file %s" % filename)
                handler.flush()
                handler.close()
                logger.removeHandler(handler)
                os.unlink(filename)
                logger.addHandler(handler)
            except Exception as e:
                print("Unable to close or delete log file: %s" % e)


        try:
            import _sqlite3
            logger.debug("SQLite3 version: %s" % _sqlite3.sqlite_version)
        except:
            logger.error("Unable to log SQLite version")

        logger.info("Loading database file %s" % database_file)
        if not os.path.exists(database_file):
            database.init_db(database_file)
        else:
            database.update_db(database_file)
        logger.info("Starting db")

        indexers.read_indexers_from_config()

        if config.settings.main.debug:
            logger.info("Debug mode enabled")

        # Clean up any "old" files from last update
        oldfiles = glob.glob("*.updated")
        if len(oldfiles) > 0:
            logger.info("Deleting %d old files remaining from update" % len(oldfiles))
            for filename in oldfiles:
                try:
                    if "hydratray" not in filename:
                        logger.debug("Deleting %s" % filename)
                        os.remove(filename)
                    else:
                        logger.debug("Not deleting %s because it's still running. TrayHelper will restart itself" % filename)
                except Exception:
                    logger.warn("Unable to delete old file %s. Please delete manually" % filename)

        host = config.settings.main.host if arguments.host is None else arguments.host
        port = config.settings.main.port if arguments.port is None else arguments.port

        socksproxy = config.settings.main.socksProxy if arguments.socksproxy is None else arguments.socksproxy
        if socksproxy:
            webaccess.set_proxies(socksproxy)
        elif config.settings.main.httpProxy:
            webaccess.set_proxies(config.settings.main.httpProxy, config.settings.main.httpsProxy)

        logger.notice("Starting web app on %s:%d" % (host, port))
        if config.settings.main.externalUrl is not None and config.settings.main.externalUrl != "":
            f = furl(config.settings.main.externalUrl)
        else:
            f = furl()
            f.host = "127.0.0.1" if config.settings.main.host == "0.0.0.0" else config.settings.main.host
            f.port = port
            f.scheme = "https" if config.settings.main.ssl else "http"
        if not arguments.nobrowser and config.settings.main.startupBrowser:
            if arguments.restarted:
                logger.info("Not opening the browser after restart")
            else:
                logger.info("Opening browser to %s" % f.url)
                webbrowser.open_new(f.url)
        else:
            logger.notice("Go to %s for the frontend" % f.url)

        web.run(host, port, basepath)
    except Exception:
        logger.exception("Fatal error occurred")
示例#13
0
import atexit
import sys
import traceback

if sys.version_info >= (3, 0) or sys.version_info < (2, 7, 9):
    sys.stderr.write("Sorry, requires Python 2.7.9 or greater, not Python 3 compatible\n")
    sys.exit(1)

import glob
import subprocess
import os
import argparse
import webbrowser
import nzbhydra

basepath = nzbhydra.getBasePath()
os.chdir(basepath)
sys.path.insert(0, os.path.join(basepath, 'libs'))

from furl import furl

from nzbhydra import log
from nzbhydra import indexers
from nzbhydra import database
from nzbhydra import web
from nzbhydra import webaccess
import nzbhydra.config as config

import requests

requests.packages.urllib3.disable_warnings()
示例#14
0
def run(arguments):
    arguments.config = arguments.config if os.path.isabs(
        arguments.config) else os.path.join(nzbhydra.getBasePath(),
                                            arguments.config)
    arguments.database = arguments.database if os.path.isabs(
        arguments.database) else os.path.join(nzbhydra.getBasePath(),
                                              arguments.database)
    nzbhydra.configFile = settings_file = arguments.config
    nzbhydra.databaseFile = database_file = arguments.database

    logger.notice("Loading settings from {}".format(settings_file))
    try:
        config.load(settings_file)
        config.save(settings_file)  # Write any new settings back to the file
        log.setup_custom_logger(arguments.logfile, arguments.quiet)
    except Exception:
        print(
            "An error occured during migrating the old config. Sorry about that...: "
        )
        traceback.print_exc(file=sys.stdout)
        print("Trying to log messages from migration...")
        config.logLogMessages()
        os._exit(-5)

    try:
        logger.info("Started")

        if arguments.daemon:
            logger.info("Daemonizing...")
            daemonize(arguments.pidfile)

        config.logLogMessages()

        if arguments.clearloganddb:
            logger.warning("Deleting log file and database now as requested")
            try:
                logger.warning("Deleting database file %s" % database_file)
                os.unlink(database_file)
            except Exception as e:
                logger.error("Unable to close or delete log file: %s" % e)

            try:
                handler = logger.handlers[1] if len(
                    logger.handlers) == 2 else logger.handlers[0]
                filename = handler.stream.name

                if filename and os.path.exists(filename):
                    logger.warn("Deleting file %s" % filename)
                handler.flush()
                handler.close()
                logger.removeHandler(handler)
                os.unlink(filename)
                logger.addHandler(handler)
            except Exception as e:
                print("Unable to close or delete log file: %s" % e)

        try:
            import _sqlite3
            logger.debug("SQLite3 version: %s" % _sqlite3.sqlite_version)
        except:
            logger.error("Unable to log SQLite version")

        logger.info("Loading database file %s" % database_file)
        if not os.path.exists(database_file):
            database.init_db(database_file)
        else:
            database.update_db(database_file)
        logger.info("Starting db")

        indexers.read_indexers_from_config()

        if config.settings.main.debug:
            logger.info("Debug mode enabled")

        # Clean up any "old" files from last update
        oldfiles = glob.glob("*.updated")
        if len(oldfiles) > 0:
            logger.info("Deleting %d old files remaining from update" %
                        len(oldfiles))
            for filename in oldfiles:
                try:
                    if "hydratray" not in filename:
                        logger.debug("Deleting %s" % filename)
                        os.remove(filename)
                    else:
                        logger.debug(
                            "Not deleting %s because it's still running. TrayHelper will restart itself"
                            % filename)
                except Exception:
                    logger.warn(
                        "Unable to delete old file %s. Please delete manually"
                        % filename)

        host = config.settings.main.host if arguments.host is None else arguments.host
        port = config.settings.main.port if arguments.port is None else arguments.port
        nzbhydra.urlBase = config.settings.main.urlBase if arguments.urlbase is None else arguments.urlbase

        socksproxy = config.settings.main.socksProxy if arguments.socksproxy is None else arguments.socksproxy
        if socksproxy:
            webaccess.set_proxies(socksproxy)
        elif config.settings.main.httpProxy:
            webaccess.set_proxies(config.settings.main.httpProxy,
                                  config.settings.main.httpsProxy)

        # Download a very small file from github to get a good estimate how many instances of hydra are running. Only executed once per installation (well, per settings.cfg instance)
        if not config.settings.main.downloadCounterExecuted and not config.settings.main.isFirstStart:
            try:
                webaccess.get(
                    "https://github.com/theotherp/apitests/releases/download/v5.0.0/downloadcounter2.zip"
                )
            except:
                pass
            config.settings.main.downloadCounterExecuted = True
            config.save()

        if config.settings.main.externalUrl is not None and config.settings.main.externalUrl != "":
            f = furl(config.settings.main.externalUrl)
            logger.notice("Starting web app on %s:%d" % (host, port))
        else:
            f = furl()

            if config.settings.main.host == "0.0.0.0":
                f.host = "127.0.0.1"
            elif config.settings.main.host == "::":
                f.host = "[::1]"
            elif ":" in config.settings.main.host:
                f.host = "[%s]" % config.settings.main.host
            else:
                f.host = config.settings.main.host
            f.port = port
            f.scheme = "https" if config.settings.main.ssl else "http"
            if nzbhydra.urlBase is not None:
                f.path = nzbhydra.urlBase + "/"
            logger.notice("Starting web app on %s:%d" % (f.host, port))
        if not arguments.nobrowser and config.settings.main.startupBrowser:
            if arguments.restarted:
                logger.info("Not opening the browser after restart")
            else:
                logger.info("Opening browser to %s" % f.url)
                webbrowser.open_new(f.url)
        else:
            logger.notice("Go to %s for the frontend" % f.url)
        if config.settings.main.isFirstStart:
            config.settings.main.isFirstStart = False
            config.save()
        web.run(host, port, basepath)
    except Exception:
        logger.exception("Fatal error occurred")
示例#15
0
import atexit
import sys
import traceback

if sys.version_info >= (3, 0) or sys.version_info < (2, 7, 9):
    sys.stderr.write(
        "Sorry, requires Python 2.7.9 or greater, not Python 3 compatible\n")
    sys.exit(1)

import glob
import subprocess
import os
import webbrowser
import nzbhydra

basepath = nzbhydra.getBasePath()
os.chdir(basepath)
sys.path.insert(0, os.path.join(basepath, 'libs'))

from furl import furl

from nzbhydra import log
from nzbhydra import indexers
from nzbhydra import database
from nzbhydra import web
from nzbhydra import webaccess
import nzbhydra.config as config

import requests
import configargparse
示例#16
0
def run(arguments):
    arguments.config = arguments.config if os.path.isabs(
        arguments.config) else os.path.join(nzbhydra.getBasePath(),
                                            arguments.config)
    arguments.database = arguments.database if os.path.isabs(
        arguments.database) else os.path.join(nzbhydra.getBasePath(),
                                              arguments.database)
    nzbhydra.configFile = settings_file = arguments.config
    nzbhydra.databaseFile = database_file = arguments.database

    logger.notice("Loading settings from {}".format(settings_file))
    try:
        config.load(settings_file)
        config.save(settings_file)  # Write any new settings back to the file
        log.setup_custom_logger(arguments.logfile, arguments.quiet)
    except Exception:
        print(
            "An error occured during migrating the old config. Sorry about that...: "
        )
        traceback.print_exc(file=sys.stdout)
        print("Trying to log messages from migration...")
        config.logLogMessages()
        os._exit(-5)

    try:
        logger.info("Started")

        if arguments.daemon:
            logger.info("Daemonizing...")
            daemonize(arguments.pidfile)

        config.logLogMessages()

        try:
            import _sqlite3
            logger.debug("SQLite3 version: %s" % _sqlite3.sqlite_version)
        except:
            logger.error("Unable to log SQLite version")

        logger.info("Loading database file %s" % database_file)
        if not os.path.exists(database_file):
            database.init_db(database_file)
        else:
            database.update_db(database_file)
        logger.info("Starting db")

        indexers.read_indexers_from_config()

        if config.settings.main.debug:
            logger.info("Debug mode enabled")

        # Clean up any "old" files from last update
        oldfiles = glob.glob("*.updated")
        if len(oldfiles) > 0:
            logger.info("Deleting %d old files remaining from update" %
                        len(oldfiles))
            for filename in oldfiles:
                try:
                    if "hydratray" not in filename:
                        logger.debug("Deleting %s" % filename)
                        os.remove(filename)
                    else:
                        logger.debug(
                            "Not deleting %s because it's still running. TrayHelper will restart itself"
                            % filename)
                except Exception:
                    logger.warn(
                        "Unable to delete old file %s. Please delete manually"
                        % filename)

        host = config.settings.main.host if arguments.host is None else arguments.host
        port = config.settings.main.port if arguments.port is None else arguments.port
        socksproxy = config.settings.main.socksProxy if arguments.socksproxy is None else arguments.socksproxy

        # SOCKS proxy settings
        if socksproxy:
            try:
                sockshost, socksport = socksproxy.split(
                    ':')  # FWIW: this won't work for literal IPv6 addresses
            except:
                logger.error('Incorrect SOCKS proxy settings "%s"' %
                             socksproxy)
                sockshost, socksport = [None, None]
            if sockshost:
                logger.info("Using SOCKS proxy at host %s and port %s" %
                            (sockshost, socksport))
                publicip = socks_proxy.setSOCKSproxy(sockshost, int(socksport))
                if publicip:
                    logger.info("Public IP address via SOCKS proxy: %s" %
                                publicip)
                else:
                    logger.error(
                        "Could not get public IP address. Is the proxy working?"
                    )
            if config.settings.main.httpProxy or config.settings.main.httpProxy:
                logger.warning(
                    "Ignoring HTTP / HTTPS proxy because SOCKS proxy is set")
        else:
            if config.settings.main.httpProxy:
                logger.info("Using HTTP proxy %s" %
                            config.settings.main.httpProxy)
                os.environ["HTTP_PROXY"] = config.settings.main.httpProxy
            if config.settings.main.httpsProxy:
                logger.info("Using HTTPS proxy %s" %
                            config.settings.main.httpsProxy)
                os.environ["HTTPS_PROXY"] = config.settings.main.httpsProxy

        logger.notice("Starting web app on %s:%d" % (host, port))
        if config.settings.main.externalUrl is not None and config.settings.main.externalUrl != "":
            f = furl(config.settings.main.externalUrl)
        else:
            f = furl()
            f.host = "127.0.0.1"
            f.port = port
            f.scheme = "https" if config.settings.main.ssl else "http"
        if not arguments.nobrowser and config.settings.main.startupBrowser:
            if arguments.restarted:
                logger.info("Not opening the browser after restart")
            else:
                logger.info("Opening browser to %s" % f.url)
                webbrowser.open_new(f.url)
        else:
            logger.notice("Go to %s for the frontend" % f.url)

        web.run(host, port, basepath)
    except Exception:
        logger.exception("Fatal error occurred")
示例#17
0
def restoreFromBackupData(zipData):
    logger.info("Attempting to restore data from backup ZIP")
    try:
        zf = zipfile.ZipFile(zipData, "r", compression=compression)
    except zipfile.BadZipfile:
        logger.error("File is not a ZIP")
        return "File is not a ZIP", 500
    containedFiles = zf.namelist()
    if "hydraBackupInfo.txt" not in containedFiles:
        noBackupInfoError = "Unable to restore from backup file because it doesn't contain a file called 'hydraBackupInfo.txt'. Either the ZIP is no NZB Hydra backup file or it was created before version 0.2.148."
        logger.error(noBackupInfoError)
        return noBackupInfoError, 500
    try:
        tempFolder = os.path.join(nzbhydra.getBasePath(), "temp")
        if os.path.exists(tempFolder):
            logger.info("Deleting old temp folder")
            shutil.rmtree(tempFolder)
        logger.info("Creating new temp folder %s" % tempFolder)
        os.mkdir(tempFolder)
    except Exception as e:
        logger.exception("Error while (re)creating temp folder")
        return "An error occured while (re)creating the temp folder: %s" % e, 500

    try:
        backupInfoString = zf.read("hydraBackupInfo.txt")
    except KeyError:
        infoMissingTest = "Unable to find hydraBackupInfo.txt. Please note that only backup files created version 0.2.148ff are supported"
        logger.error(infoMissingTest)
        return infoMissingTest
    try:
        backupInfo = json.loads(backupInfoString)
        logger.info("Found backup info in archive: %s" % backupInfoString)
        configFileName = backupInfo["configFile"]
        databaseFileName = backupInfo["databaseFile"]
        logger.info("Extracting backup data to temp folder %s" % tempFolder)
        zf.extract(configFileName, tempFolder)
        zf.extract(databaseFileName, tempFolder)
    except Exception as e:
        logger.exception("Error while extracting backup ZIP")
        return "An error occured while extracting the data from the backup ZIP: %s" % e, 500

    try:
        logger.info("Shutting down database")
        dbStopped = database.db.stop()
        if dbStopped:
            database.db.close()
    except Exception as e:
        logger.exception("Error while shutting down database")
        try:
            database.db.start()
        except Exception as e:
            return "Unable to recover from database error: %s. You might need to restart" % e, 500
        return "An error occured while shutting down the database: %s" % e, 500

    databaseFileRestored = False
    databaseFileTempBackup = None
    configFileTempBackup = None
    try:
        logger.info("Starting to restore database file to %s" % nzbhydra.databaseFile)
        databaseFileTempBackup = nzbhydra.databaseFile + ".tempBackup"
        logger.info("Renaming database file %s to temporary backup file %s" % (nzbhydra.databaseFile, databaseFileTempBackup))
        os.rename(nzbhydra.databaseFile, databaseFileTempBackup)
        databaseTempFile = os.path.join(tempFolder, os.path.basename(databaseFileName))
        logger.info("Replacing database file %s with extracted file %s" % (nzbhydra.databaseFile, databaseTempFile))
        os.rename(databaseTempFile, nzbhydra.databaseFile)
        databaseFileRestored = True

        logger.info("Starting to restore settings file to %s" % nzbhydra.configFile)
        configFileTempBackup = nzbhydra.configFile + ".tempBackup"
        logger.info("Renaming config file %s to temporary backup file %s" % (nzbhydra.configFile, configFileTempBackup))
        os.rename(nzbhydra.configFile, configFileTempBackup)
        configTempFile = os.path.join(tempFolder, os.path.basename(configFileName))
        logger.info("Replacing config file %s with extracted file %s" % (nzbhydra.configFile, configTempFile))
        os.rename(configTempFile, nzbhydra.configFile)

        logger.info("Restoration completed successfully.")
    except Exception as e:
        logger.exception("Error while restoring files")
        logger.info("Restoring original state")
        if databaseFileRestored:
            if databaseFileTempBackup is not None:
                logger.info("Moving temporary database backup file %s back to %s" % (databaseFileTempBackup, nzbhydra.databaseFile))
                if os.path.exists(nzbhydra.databaseFile):
                    os.unlink(nzbhydra.databaseFile)
                os.rename(databaseFileTempBackup, nzbhydra.databaseFile)
            else:
                logger.error("Unable to bring back database file to state before restore")
        if configFileTempBackup is not None:
            logger.info("Moving temporary config backup file %s back to %s" % (configFileTempBackup, nzbhydra.configFile))
            if os.path.exists(nzbhydra.configFile):
                os.unlink(nzbhydra.configFile)
            os.rename(configFileTempBackup, nzbhydra.configFile)
        else:
            logger.error("Unable to bring back config file to state before restore")
        return "Error while restoring files: %s. Original state was restored." % e, 500
    finally:
        try:
            if databaseFileTempBackup is not None and os.path.exists(databaseFileTempBackup):
                logger.info("Deleting temporary backup of database file %s" % databaseFileTempBackup)
                os.unlink(databaseFileTempBackup)
            if configFileTempBackup is not None and os.path.exists(configFileTempBackup):
                logger.info("Deleting temporary backup of config file %s" % configFileTempBackup)
                os.unlink(configFileTempBackup)
            logger.info("Deleting temp folder %s" % tempFolder)
            shutil.rmtree(tempFolder)
        except Exception as e:
            logger.error("Error while cleaning up")

    return "OK"