Lint
This commit is contained in:
parent
63d8c591d0
commit
0435f399f1
2 changed files with 90 additions and 75 deletions
|
@ -1,5 +1,6 @@
|
||||||
#!/usr/bin/python3
|
#!/usr/bin/python3
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
# pylint: disable=too-many-lines
|
||||||
"""
|
"""
|
||||||
Configurator for Home Assistant.
|
Configurator for Home Assistant.
|
||||||
https://github.com/danielperna84/hass-configurator
|
https://github.com/danielperna84/hass-configurator
|
||||||
|
@ -82,6 +83,7 @@ NOTIFY_SERVICE_DEFAULT = "persistent_notification.create"
|
||||||
NOTIFY_SERVICE = NOTIFY_SERVICE_DEFAULT
|
NOTIFY_SERVICE = NOTIFY_SERVICE_DEFAULT
|
||||||
### End of options
|
### End of options
|
||||||
|
|
||||||
|
|
||||||
LOGLEVEL = logging.INFO
|
LOGLEVEL = logging.INFO
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
LOG.setLevel(LOGLEVEL)
|
LOG.setLevel(LOGLEVEL)
|
||||||
|
@ -94,6 +96,7 @@ RELEASEURL = "https://api.github.com/repos/danielperna84/hass-configurator/relea
|
||||||
VERSION = "0.3.0"
|
VERSION = "0.3.0"
|
||||||
BASEDIR = "."
|
BASEDIR = "."
|
||||||
DEV = False
|
DEV = False
|
||||||
|
LISTENPORT = None
|
||||||
TOTP = None
|
TOTP = None
|
||||||
HTTPD = None
|
HTTPD = None
|
||||||
FAIL2BAN_IPS = {}
|
FAIL2BAN_IPS = {}
|
||||||
|
@ -3413,6 +3416,7 @@ editor.on('change', queue_lint);
|
||||||
</body>
|
</body>
|
||||||
</html>""")
|
</html>""")
|
||||||
|
|
||||||
|
# pylint: disable=unused-argument
|
||||||
def signal_handler(sig, frame):
|
def signal_handler(sig, frame):
|
||||||
global HTTPD
|
global HTTPD
|
||||||
LOG.info("Got signal: %s. Shutting down server", str(sig))
|
LOG.info("Got signal: %s. Shutting down server", str(sig))
|
||||||
|
@ -3420,11 +3424,11 @@ def signal_handler(sig, frame):
|
||||||
sys.exit(0)
|
sys.exit(0)
|
||||||
|
|
||||||
def load_settings(settingsfile):
|
def load_settings(settingsfile):
|
||||||
global LISTENIP, PORT, BASEPATH, SSL_CERTIFICATE, SSL_KEY, HASS_API, \
|
global LISTENIP, LISTENPORT, BASEPATH, SSL_CERTIFICATE, SSL_KEY, HASS_API, \
|
||||||
HASS_API_PASSWORD, CREDENTIALS, ALLOWED_NETWORKS, BANNED_IPS, BANLIMIT, \
|
HASS_API_PASSWORD, CREDENTIALS, ALLOWED_NETWORKS, BANNED_IPS, BANLIMIT, \
|
||||||
DEV, IGNORE_PATTERN, DIRSFIRST, SESAME, VERIFY_HOSTNAME, ENFORCE_BASEPATH, \
|
DEV, IGNORE_PATTERN, DIRSFIRST, SESAME, VERIFY_HOSTNAME, ENFORCE_BASEPATH, \
|
||||||
ENV_PREFIX, NOTIFY_SERVICE, USERNAME, PASSWORD, SESAME_TOTP_SECRET, TOTP, \
|
ENV_PREFIX, NOTIFY_SERVICE, USERNAME, PASSWORD, SESAME_TOTP_SECRET, TOTP, \
|
||||||
GIT, REPO
|
GIT, REPO, PORT
|
||||||
settings = {}
|
settings = {}
|
||||||
if settingsfile:
|
if settingsfile:
|
||||||
try:
|
try:
|
||||||
|
@ -3513,11 +3517,17 @@ def get_dircontent(path, repo=None):
|
||||||
unstaged = {}
|
unstaged = {}
|
||||||
try:
|
try:
|
||||||
for element in repo.index.diff("HEAD"):
|
for element in repo.index.diff("HEAD"):
|
||||||
staged["%s%s%s" % (repo.working_dir, os.sep, "%s"%os.sep.join(element.b_path.split('/')))] = element.change_type
|
staged["%s%s%s" % (repo.working_dir,
|
||||||
|
os.sep,
|
||||||
|
"%s"%os.sep.join(
|
||||||
|
element.b_path.split('/')))] = element.change_type
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
LOG.warning("Exception: %s", str(err))
|
LOG.warning("Exception: %s", str(err))
|
||||||
for element in repo.index.diff(None):
|
for element in repo.index.diff(None):
|
||||||
unstaged["%s%s%s" % (repo.working_dir, os.sep, "%s"%os.sep.join(element.b_path.split('/')))] = element.change_type
|
unstaged["%s%s%s" % (repo.working_dir,
|
||||||
|
os.sep,
|
||||||
|
"%s"%os.sep.join(
|
||||||
|
element.b_path.split('/')))] = element.change_type
|
||||||
else:
|
else:
|
||||||
untracked = []
|
untracked = []
|
||||||
staged = {}
|
staged = {}
|
||||||
|
@ -3527,8 +3537,8 @@ def get_dircontent(path, repo=None):
|
||||||
dirlist = [x for x in os.listdir(path) if os.path.isdir(os.path.join(path, x))]
|
dirlist = [x for x in os.listdir(path) if os.path.isdir(os.path.join(path, x))]
|
||||||
filelist = [x for x in os.listdir(path) if not os.path.isdir(os.path.join(path, x))]
|
filelist = [x for x in os.listdir(path) if not os.path.isdir(os.path.join(path, x))]
|
||||||
if DIRSFIRST:
|
if DIRSFIRST:
|
||||||
return sorted(dirlist, key=lambda x: x.lower()) + sorted(filelist, key=lambda x: x.lower())
|
return sorted(dirlist, key=lambda x: x.lower()) + \
|
||||||
else:
|
sorted(filelist, key=lambda x: x.lower())
|
||||||
return sorted(dirlist + filelist, key=lambda x: x.lower())
|
return sorted(dirlist + filelist, key=lambda x: x.lower())
|
||||||
|
|
||||||
for elem in sorted_file_list():
|
for elem in sorted_file_list():
|
||||||
|
@ -3596,7 +3606,8 @@ def password_problems(password, name="UNKNOWN"):
|
||||||
exp = len(password) ** len(set(password))
|
exp = len(password) ** len(set(password))
|
||||||
score = exp / quota / 8
|
score = exp / quota / 8
|
||||||
if score < 65536:
|
if score < 65536:
|
||||||
LOG.warning("Password %s does not contain enough unique characters (%i)" % (name, len(set(password))))
|
LOG.warning("Password %s does not contain enough unique characters (%i)" % (
|
||||||
|
name, len(set(password))))
|
||||||
problems += 8
|
problems += 8
|
||||||
return problems
|
return problems
|
||||||
|
|
||||||
|
@ -3622,15 +3633,18 @@ def verify_hostname(request_hostname):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
class RequestHandler(BaseHTTPRequestHandler):
|
class RequestHandler(BaseHTTPRequestHandler):
|
||||||
|
# pylint: disable=redefined-builtin
|
||||||
def log_message(self, format, *args):
|
def log_message(self, format, *args):
|
||||||
LOG.info("%s - %s" % (self.client_address[0], format % args))
|
LOG.info("%s - %s" % (self.client_address[0], format % args))
|
||||||
return
|
return
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
def do_BLOCK(self, status=420, reason="Policy not fulfilled"):
|
def do_BLOCK(self, status=420, reason="Policy not fulfilled"):
|
||||||
self.send_response(status)
|
self.send_response(status)
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(bytes(reason, "utf8"))
|
self.wfile.write(bytes(reason, "utf8"))
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
def do_GET(self):
|
def do_GET(self):
|
||||||
if not verify_hostname(self.headers.get('Host', '')):
|
if not verify_hostname(self.headers.get('Host', '')):
|
||||||
self.do_BLOCK(403, "Forbidden")
|
self.do_BLOCK(403, "Forbidden")
|
||||||
|
@ -3691,7 +3705,9 @@ class RequestHandler(BaseHTTPRequestHandler):
|
||||||
if os.path.isfile(os.path.join(BASEDIR.encode('utf-8'), filename)):
|
if os.path.isfile(os.path.join(BASEDIR.encode('utf-8'), filename)):
|
||||||
with open(os.path.join(BASEDIR.encode('utf-8'), filename), 'rb') as fptr:
|
with open(os.path.join(BASEDIR.encode('utf-8'), filename), 'rb') as fptr:
|
||||||
filecontent = fptr.read()
|
filecontent = fptr.read()
|
||||||
self.send_header('Content-Disposition', 'attachment; filename=%s' % filename.decode('utf-8').split(os.sep)[-1])
|
self.send_header(
|
||||||
|
'Content-Disposition',
|
||||||
|
'attachment; filename=%s' % filename.decode('utf-8').split(os.sep)[-1])
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(filecontent)
|
self.wfile.write(filecontent)
|
||||||
return
|
return
|
||||||
|
@ -3731,7 +3747,8 @@ class RequestHandler(BaseHTTPRequestHandler):
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
LOG.debug("Exception (no repo): %s" % str(err))
|
LOG.debug("Exception (no repo): %s" % str(err))
|
||||||
dircontent = get_dircontent(dirpath.decode('utf-8'), repo)
|
dircontent = get_dircontent(dirpath.decode('utf-8'), repo)
|
||||||
filedata = {'content': dircontent,
|
filedata = {
|
||||||
|
'content': dircontent,
|
||||||
'abspath': os.path.abspath(dirpath).decode('utf-8'),
|
'abspath': os.path.abspath(dirpath).decode('utf-8'),
|
||||||
'parent': os.path.dirname(os.path.abspath(dirpath)).decode('utf-8'),
|
'parent': os.path.dirname(os.path.abspath(dirpath)).decode('utf-8'),
|
||||||
'branches': branches,
|
'branches': branches,
|
||||||
|
@ -3967,13 +3984,15 @@ class RequestHandler(BaseHTTPRequestHandler):
|
||||||
ws_api = "%s://%swebsocket" % (
|
ws_api = "%s://%swebsocket" % (
|
||||||
"wss" if protocol == 'https' else 'ws', uri
|
"wss" if protocol == 'https' else 'ws', uri
|
||||||
)
|
)
|
||||||
html = get_html().safe_substitute(services=services,
|
html = get_html().safe_substitute(
|
||||||
|
services=services,
|
||||||
events=events,
|
events=events,
|
||||||
states=states,
|
states=states,
|
||||||
loadfile=loadfile,
|
loadfile=loadfile,
|
||||||
current=VERSION,
|
current=VERSION,
|
||||||
versionclass=color,
|
versionclass=color,
|
||||||
githidden="" if GIT else "hiddendiv",
|
githidden="" if GIT else "hiddendiv",
|
||||||
|
# pylint: disable=anomalous-backslash-in-string
|
||||||
separator="\%s" % os.sep if os.sep == "\\" else os.sep,
|
separator="\%s" % os.sep if os.sep == "\\" else os.sep,
|
||||||
listening_address="%s://%s:%i" % (
|
listening_address="%s://%s:%i" % (
|
||||||
'https' if SSL_CERTIFICATE else 'http', LISTENIP, PORT),
|
'https' if SSL_CERTIFICATE else 'http', LISTENIP, PORT),
|
||||||
|
@ -3987,6 +4006,7 @@ class RequestHandler(BaseHTTPRequestHandler):
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(bytes("File not found", "utf8"))
|
self.wfile.write(bytes("File not found", "utf8"))
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
def do_POST(self):
|
def do_POST(self):
|
||||||
global ALLOWED_NETWORKS, BANNED_IPS
|
global ALLOWED_NETWORKS, BANNED_IPS
|
||||||
if not verify_hostname(self.headers.get('Host', '')):
|
if not verify_hostname(self.headers.get('Host', '')):
|
||||||
|
@ -4042,11 +4062,11 @@ class RequestHandler(BaseHTTPRequestHandler):
|
||||||
response['message'] = "File too big: %i" % read
|
response['message'] = "File too big: %i" % read
|
||||||
self.wfile.write(bytes(json.dumps(response), "utf8"))
|
self.wfile.write(bytes(json.dumps(response), "utf8"))
|
||||||
return
|
return
|
||||||
else:
|
|
||||||
form = cgi.FieldStorage(
|
form = cgi.FieldStorage(
|
||||||
fp=self.rfile,
|
fp=self.rfile,
|
||||||
headers=self.headers,
|
headers=self.headers,
|
||||||
environ={'REQUEST_METHOD': 'POST',
|
environ={
|
||||||
|
'REQUEST_METHOD': 'POST',
|
||||||
'CONTENT_TYPE': self.headers['Content-Type'],
|
'CONTENT_TYPE': self.headers['Content-Type'],
|
||||||
})
|
})
|
||||||
filename = form['file'].filename
|
filename = form['file'].filename
|
||||||
|
@ -4160,7 +4180,8 @@ class RequestHandler(BaseHTTPRequestHandler):
|
||||||
# pylint: disable=not-callable
|
# pylint: disable=not-callable
|
||||||
repo = REPO(addpath,
|
repo = REPO(addpath,
|
||||||
search_parent_directories=True)
|
search_parent_directories=True)
|
||||||
filepath = "/".join(addpath.split(os.sep)[len(repo.working_dir.split(os.sep)):])
|
filepath = "/".join(
|
||||||
|
addpath.split(os.sep)[len(repo.working_dir.split(os.sep)):])
|
||||||
response['path'] = filepath
|
response['path'] = filepath
|
||||||
try:
|
try:
|
||||||
repo.index.add([filepath])
|
repo.index.add([filepath])
|
||||||
|
@ -4196,10 +4217,13 @@ class RequestHandler(BaseHTTPRequestHandler):
|
||||||
# pylint: disable=not-callable
|
# pylint: disable=not-callable
|
||||||
repo = REPO(diffpath,
|
repo = REPO(diffpath,
|
||||||
search_parent_directories=True)
|
search_parent_directories=True)
|
||||||
filepath = "/".join(diffpath.split(os.sep)[len(repo.working_dir.split(os.sep)):])
|
filepath = "/".join(
|
||||||
|
diffpath.split(os.sep)[len(repo.working_dir.split(os.sep)):])
|
||||||
response['path'] = filepath
|
response['path'] = filepath
|
||||||
try:
|
try:
|
||||||
diff = repo.index.diff(None, create_patch=True, paths=filepath)[0].diff.decode("utf-8")
|
diff = repo.index.diff(None,
|
||||||
|
create_patch=True,
|
||||||
|
paths=filepath)[0].diff.decode("utf-8")
|
||||||
response['error'] = False
|
response['error'] = False
|
||||||
response['message'] = diff
|
response['message'] = diff
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
|
@ -4546,21 +4570,21 @@ class RequestHandler(BaseHTTPRequestHandler):
|
||||||
if 'ip' in postvars.keys() and 'method' in postvars.keys():
|
if 'ip' in postvars.keys() and 'method' in postvars.keys():
|
||||||
if postvars['ip'] and postvars['method']:
|
if postvars['ip'] and postvars['method']:
|
||||||
try:
|
try:
|
||||||
ip = unquote(postvars['ip'][0])
|
ip_address = unquote(postvars['ip'][0])
|
||||||
method = unquote(postvars['method'][0])
|
method = unquote(postvars['method'][0])
|
||||||
if method == 'unban':
|
if method == 'unban':
|
||||||
if ip in BANNED_IPS:
|
if ip_address in BANNED_IPS:
|
||||||
BANNED_IPS.remove(ip)
|
BANNED_IPS.remove(ip_address)
|
||||||
response['error'] = False
|
response['error'] = False
|
||||||
elif method == 'ban':
|
elif method == 'ban':
|
||||||
ipaddress.ip_network(ip)
|
ipaddress.ip_network(ip_address)
|
||||||
BANNED_IPS.append(ip)
|
BANNED_IPS.append(ip_address)
|
||||||
else:
|
else:
|
||||||
response['error'] = True
|
response['error'] = True
|
||||||
self.send_response(200)
|
self.send_response(200)
|
||||||
self.send_header('Content-type', 'text/json')
|
self.send_header('Content-type', 'text/json')
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
response['message'] = "BANNED_IPS (%s): %s" % (method, ip)
|
response['message'] = "BANNED_IPS (%s): %s" % (method, ip_address)
|
||||||
self.wfile.write(bytes(json.dumps(response), "utf8"))
|
self.wfile.write(bytes(json.dumps(response), "utf8"))
|
||||||
return
|
return
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
|
@ -4583,6 +4607,7 @@ class AuthHandler(RequestHandler):
|
||||||
self.end_headers()
|
self.end_headers()
|
||||||
self.wfile.write(bytes(reason, "utf8"))
|
self.wfile.write(bytes(reason, "utf8"))
|
||||||
|
|
||||||
|
# pylint: disable=invalid-name
|
||||||
def do_AUTHHEAD(self):
|
def do_AUTHHEAD(self):
|
||||||
LOG.info("Requesting authorization")
|
LOG.info("Requesting authorization")
|
||||||
self.send_response(401)
|
self.send_response(401)
|
||||||
|
@ -4738,15 +4763,15 @@ def main(args):
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
LOG.warning("Exception while checking passwords: %s" % err)
|
LOG.warning("Exception while checking passwords: %s" % err)
|
||||||
|
|
||||||
CustomServer = SimpleServer
|
custom_server = SimpleServer
|
||||||
if ':' in LISTENIP:
|
if ':' in LISTENIP:
|
||||||
CustomServer.address_family = socket.AF_INET6
|
custom_server.address_family = socket.AF_INET6
|
||||||
server_address = (LISTENIP, PORT)
|
server_address = (LISTENIP, PORT)
|
||||||
if USERNAME and PASSWORD:
|
if USERNAME and PASSWORD:
|
||||||
Handler = AuthHandler
|
handler = AuthHandler
|
||||||
else:
|
else:
|
||||||
Handler = RequestHandler
|
handler = RequestHandler
|
||||||
HTTPD = CustomServer(server_address, Handler)
|
HTTPD = custom_server(server_address, handler)
|
||||||
if SSL_CERTIFICATE:
|
if SSL_CERTIFICATE:
|
||||||
HTTPD.socket = ssl.wrap_socket(HTTPD.socket,
|
HTTPD.socket = ssl.wrap_socket(HTTPD.socket,
|
||||||
certfile=SSL_CERTIFICATE,
|
certfile=SSL_CERTIFICATE,
|
||||||
|
|
14
pylintrc
14
pylintrc
|
@ -2,22 +2,12 @@
|
||||||
reports=no
|
reports=no
|
||||||
|
|
||||||
disable=
|
disable=
|
||||||
too-many-lines,
|
|
||||||
missing-docstring,
|
missing-docstring,
|
||||||
global-statement,
|
global-statement,
|
||||||
global-variable-not-assigned,
|
logging-not-lazy,
|
||||||
|
broad-except,
|
||||||
too-many-return-statements,
|
too-many-return-statements,
|
||||||
too-many-nested-blocks,
|
too-many-nested-blocks,
|
||||||
too-many-statements,
|
too-many-statements,
|
||||||
too-many-branches,
|
too-many-branches,
|
||||||
too-many-locals,
|
too-many-locals,
|
||||||
unused-argument,
|
|
||||||
logging-not-lazy,
|
|
||||||
invalid-name,
|
|
||||||
broad-except,
|
|
||||||
line-too-long,
|
|
||||||
unnecessary-pass,
|
|
||||||
anomalous-backslash-in-string,
|
|
||||||
redefined-variable-type,
|
|
||||||
redefined-builtin,
|
|
||||||
no-else-return,
|
|
Loading…
Add table
Add a link
Reference in a new issue