# -*- coding: utf-8 -*- # This file is part of the Calibre-Web (https://github.com/janeczku/calibre-web) # Copyright (C) 2018 OzzieIsaacs # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . import sys import os import argparse import socket from .constants import CONFIG_DIR as _CONFIG_DIR from .constants import STABLE_VERSION as _STABLE_VERSION from .constants import NIGHTLY_VERSION as _NIGHTLY_VERSION from .constants import DEFAULT_SETTINGS_FILE, DEFAULT_GDRIVE_FILE def version_info(): if _NIGHTLY_VERSION[1].startswith('$Format'): return "Calibre-Web version: %s - unknown git-clone" % _STABLE_VERSION.replace("b", " Beta") return "Calibre-Web version: %s -%s" % (_STABLE_VERSION.replace("b", " Beta"), _NIGHTLY_VERSION[1]) class CliParameter(object): def __init__(self): self.user_credentials = None self.ip_address = None self.allow_localhost = None self.reconnect_enable = None self.memory_backend = None self.dry_run = None self.certfilepath = None self.keyfilepath = None self.gd_path = None self.settings_path = None self.logpath = None def init(self): self.arg_parser() def arg_parser(self): parser = argparse.ArgumentParser(description='Calibre Web is a web app providing ' 'a interface for browsing, reading and downloading eBooks\n', prog='cps.py') parser.add_argument('-p', metavar='path', help='path and name to settings db, e.g. /opt/cw.db') parser.add_argument('-g', metavar='path', help='path and name to gdrive db, e.g. /opt/gd.db') parser.add_argument('-c', metavar='path', help='path and name to SSL certfile, ' 'e.g. /opt/test.cert, works only in combination with keyfile') parser.add_argument('-k', metavar='path', help='path and name to SSL keyfile, e.g. /opt/test.key, ' 'works only in combination with certfile') parser.add_argument('-o', metavar='path', help='path and name Calibre-Web logfile') parser.add_argument('-v', '--version', action='version', help='Shows version number ' 'and exits Calibre-Web', version=version_info()) parser.add_argument('-i', metavar='ip-address', help='Server IP-Address to listen') parser.add_argument('-m', action='store_true', help='Use Memory-backend as limiter backend, use this parameter ' 'in case of miss configured backend') parser.add_argument('-s', metavar='user:pass', help='Sets specific username to new password and exits Calibre-Web') parser.add_argument('-l', action='store_true', help='Allow loading covers from localhost') parser.add_argument('-d', action='store_true', help='Dry run of updater to check file permissions ' 'in advance and exits Calibre-Web') parser.add_argument('-r', action='store_true', help='Enable public database reconnect ' 'route under /reconnect') args = parser.parse_args() self.logpath = args.o or "" self.settings_path = args.p or os.path.join(_CONFIG_DIR, DEFAULT_SETTINGS_FILE) self.gd_path = args.g or os.path.join(_CONFIG_DIR, DEFAULT_GDRIVE_FILE) if os.path.isdir(self.settings_path): self.settings_path = os.path.join(self.settings_path, DEFAULT_SETTINGS_FILE) if os.path.isdir(self.gd_path): self.gd_path = os.path.join(self.gd_path, DEFAULT_GDRIVE_FILE) # handle and check parameter for ssl encryption self.certfilepath = None self.keyfilepath = None if args.c: if os.path.isfile(args.c): self.certfilepath = args.c else: print("Certfile path is invalid. Exiting...") sys.exit(1) if args.c == "": self.certfilepath = "" if args.k: if os.path.isfile(args.k): self.keyfilepath = args.k else: print("Keyfile path is invalid. Exiting...") sys.exit(1) if (args.k and not args.c) or (not args.k and args.c): print("Certfile and Keyfile have to be used together. Exiting...") sys.exit(1) if args.k == "": self.keyfilepath = "" # overwrite limiter backend self.memory_backend = args.m or None # dry run updater self.dry_run = args.d or None # enable reconnect endpoint for docker database reconnect self.reconnect_enable = args.r or os.environ.get("CALIBRE_RECONNECT", None) # load covers from localhost self.allow_localhost = args.l or os.environ.get("CALIBRE_LOCALHOST", None) # handle and check ip address argument self.ip_address = args.i or None if self.ip_address: try: # try to parse the given ip address with socket if hasattr(socket, 'inet_pton'): if ':' in self.ip_address: socket.inet_pton(socket.AF_INET6, self.ip_address) else: socket.inet_pton(socket.AF_INET, self.ip_address) else: # on Windows python < 3.4, inet_pton is not available # inet_atom only handles IPv4 addresses socket.inet_aton(self.ip_address) except socket.error as err: print(self.ip_address, ':', err) sys.exit(1) # handle and check user password argument self.user_credentials = args.s or None if self.user_credentials and ":" not in self.user_credentials: print("No valid 'username:password' format") sys.exit(3)