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
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
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
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
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
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
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
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
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"
def getBackupFileByFilename(filename): backup_folder = os.path.join(nzbhydra.getBasePath(), "backup") backup_file = os.path.join(backup_folder, filename) return backup_file
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")
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()
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")
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
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")
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"