mirror of
				https://github.com/mail-in-a-box/mailinabox.git
				synced 2025-11-03 19:30:54 +00:00 
			
		
		
		
	pep8 cleanup of Python source files
pep8 (https://www.python.org/dev/peps/pep-0008/) is the commonly accepted and widely adopted code style convention for Python. I used pycodestyle (https://pycodestyle.readthedocs.io/en/latest/) to check for pep8 compatibility. Especially the mix of tabs and spaces in the Python files makes it hard to work with. I switched to spaces, because that's what pep8 expects and the majority of Python programmers use.
This commit is contained in:
		
							parent
							
								
									c3605f6211
								
							
						
					
					
						commit
						8cea79de8b
					
				@ -22,7 +22,8 @@
 | 
				
			|||||||
# NAME VAL
 | 
					# NAME VAL
 | 
				
			||||||
#   UE
 | 
					#   UE
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import sys, re
 | 
					import sys
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# sanity check
 | 
					# sanity check
 | 
				
			||||||
if len(sys.argv) < 3:
 | 
					if len(sys.argv) < 3:
 | 
				
			||||||
@ -84,18 +85,20 @@ while len(input_lines) > 0:
 | 
				
			|||||||
        # Check that this line contain this setting from the command-line arguments.
 | 
					        # Check that this line contain this setting from the command-line arguments.
 | 
				
			||||||
        name, val = settings[i].split("=", 1)
 | 
					        name, val = settings[i].split("=", 1)
 | 
				
			||||||
        m = re.match(
 | 
					        m = re.match(
 | 
				
			||||||
			   "(\s*)"
 | 
					               "(\s*)" +
 | 
				
			||||||
			 + "(" + re.escape(comment_char) + "\s*)?"
 | 
					               "(" + re.escape(comment_char) + "\s*)?" +
 | 
				
			||||||
			 + re.escape(name) + delimiter_re + "(.*?)\s*$",
 | 
					               re.escape(name) + delimiter_re + "(.*?)\s*$",
 | 
				
			||||||
               line, re.S)
 | 
					               line, re.S)
 | 
				
			||||||
		if not m: continue
 | 
					        if not m:
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
        indent, is_comment, existing_val = m.groups()
 | 
					        indent, is_comment, existing_val = m.groups()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # If this is already the setting, do nothing.
 | 
					        # If this is already the setting, do nothing.
 | 
				
			||||||
        if is_comment is None and existing_val == val:
 | 
					        if is_comment is None and existing_val == val:
 | 
				
			||||||
            # It may be that we've already inserted this setting higher
 | 
					            # It may be that we've already inserted this setting higher
 | 
				
			||||||
            # in the file so check for that first.
 | 
					            # in the file so check for that first.
 | 
				
			||||||
			if i in found: break
 | 
					            if i in found:
 | 
				
			||||||
 | 
					                break
 | 
				
			||||||
            buf += line
 | 
					            buf += line
 | 
				
			||||||
            found.add(i)
 | 
					            found.add(i)
 | 
				
			||||||
            break
 | 
					            break
 | 
				
			||||||
 | 
				
			|||||||
@ -1,6 +1,12 @@
 | 
				
			|||||||
#!/usr/bin/python3
 | 
					#!/usr/bin/python3
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import sys, getpass, urllib.request, urllib.error, json, re
 | 
					import sys
 | 
				
			||||||
 | 
					import getpass
 | 
				
			||||||
 | 
					import urllib.request
 | 
				
			||||||
 | 
					import urllib.error
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def mgmt(cmd, data=None, is_json=False):
 | 
					def mgmt(cmd, data=None, is_json=False):
 | 
				
			||||||
    # The base URL for the management daemon. (Listens on IPv4 only.)
 | 
					    # The base URL for the management daemon. (Listens on IPv4 only.)
 | 
				
			||||||
@ -17,16 +23,19 @@ def mgmt(cmd, data=None, is_json=False):
 | 
				
			|||||||
                print(e.read().decode("utf8"))
 | 
					                print(e.read().decode("utf8"))
 | 
				
			||||||
            except:
 | 
					            except:
 | 
				
			||||||
                pass
 | 
					                pass
 | 
				
			||||||
			print("The management daemon refused access. The API key file may be out of sync. Try 'service mailinabox restart'.", file=sys.stderr)
 | 
					            print("The management daemon refused access. The API key file may be out of sync. \
 | 
				
			||||||
 | 
					                   Try 'service mailinabox restart'.", file=sys.stderr)
 | 
				
			||||||
        elif hasattr(e, 'read'):
 | 
					        elif hasattr(e, 'read'):
 | 
				
			||||||
            print(e.read().decode('utf8'), file=sys.stderr)
 | 
					            print(e.read().decode('utf8'), file=sys.stderr)
 | 
				
			||||||
        else:
 | 
					        else:
 | 
				
			||||||
            print(e, file=sys.stderr)
 | 
					            print(e, file=sys.stderr)
 | 
				
			||||||
        sys.exit(1)
 | 
					        sys.exit(1)
 | 
				
			||||||
    resp = response.read().decode('utf8')
 | 
					    resp = response.read().decode('utf8')
 | 
				
			||||||
	if is_json: resp = json.loads(resp)
 | 
					    if is_json:
 | 
				
			||||||
 | 
					        resp = json.loads(resp)
 | 
				
			||||||
    return resp
 | 
					    return resp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def read_password():
 | 
					def read_password():
 | 
				
			||||||
    while True:
 | 
					    while True:
 | 
				
			||||||
        first = getpass.getpass('password: ')
 | 
					        first = getpass.getpass('password: ')
 | 
				
			||||||
@ -43,6 +52,7 @@ def read_password():
 | 
				
			|||||||
        break
 | 
					        break
 | 
				
			||||||
    return first
 | 
					    return first
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def setup_key_auth(mgmt_uri):
 | 
					def setup_key_auth(mgmt_uri):
 | 
				
			||||||
    key = open('/var/lib/mailinabox/api.key').read().strip()
 | 
					    key = open('/var/lib/mailinabox/api.key').read().strip()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -55,6 +65,7 @@ def setup_key_auth(mgmt_uri):
 | 
				
			|||||||
    opener = urllib.request.build_opener(auth_handler)
 | 
					    opener = urllib.request.build_opener(auth_handler)
 | 
				
			||||||
    urllib.request.install_opener(opener)
 | 
					    urllib.request.install_opener(opener)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if len(sys.argv) < 2:
 | 
					if len(sys.argv) < 2:
 | 
				
			||||||
    print("Usage: ")
 | 
					    print("Usage: ")
 | 
				
			||||||
    print("  tools/mail.py user  (lists users)")
 | 
					    print("  tools/mail.py user  (lists users)")
 | 
				
			||||||
@ -77,7 +88,8 @@ elif sys.argv[1] == "user" and len(sys.argv) == 2:
 | 
				
			|||||||
    users = mgmt("/mail/users?format=json", is_json=True)
 | 
					    users = mgmt("/mail/users?format=json", is_json=True)
 | 
				
			||||||
    for domain in users:
 | 
					    for domain in users:
 | 
				
			||||||
        for user in domain["users"]:
 | 
					        for user in domain["users"]:
 | 
				
			||||||
			if user['status'] == 'inactive': continue
 | 
					            if user['status'] == 'inactive':
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
            print(user['email'], end='')
 | 
					            print(user['email'], end='')
 | 
				
			||||||
            if "admin" in user['privileges']:
 | 
					            if "admin" in user['privileges']:
 | 
				
			||||||
                print("*", end='')
 | 
					                print("*", end='')
 | 
				
			||||||
@ -128,4 +140,3 @@ elif sys.argv[1] == "alias" and sys.argv[2] == "remove" and len(sys.argv) == 4:
 | 
				
			|||||||
else:
 | 
					else:
 | 
				
			||||||
    print("Invalid command-line arguments.")
 | 
					    print("Invalid command-line arguments.")
 | 
				
			||||||
    sys.exit(1)
 | 
					    sys.exit(1)
 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,11 @@
 | 
				
			|||||||
# looking at accesses to the bootstrap.sh script (which is currently at the URL
 | 
					# looking at accesses to the bootstrap.sh script (which is currently at the URL
 | 
				
			||||||
# .../setup.sh).
 | 
					# .../setup.sh).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import re, glob, gzip, os.path, json
 | 
					import re
 | 
				
			||||||
 | 
					import glob
 | 
				
			||||||
 | 
					import gzip
 | 
				
			||||||
 | 
					import os.path
 | 
				
			||||||
 | 
					import json
 | 
				
			||||||
import dateutil.parser
 | 
					import dateutil.parser
 | 
				
			||||||
 | 
					
 | 
				
			||||||
outfn = "/home/user-data/www/mailinabox.email/install-stats.json"
 | 
					outfn = "/home/user-data/www/mailinabox.email/install-stats.json"
 | 
				
			||||||
@ -26,7 +30,8 @@ for fn in glob.glob("/var/log/nginx/access.log*"):
 | 
				
			|||||||
    with f:
 | 
					    with f:
 | 
				
			||||||
        for line in f:
 | 
					        for line in f:
 | 
				
			||||||
            # Find lines that are GETs on the bootstrap script by either curl or wget.
 | 
					            # Find lines that are GETs on the bootstrap script by either curl or wget.
 | 
				
			||||||
			# (Note that we purposely skip ...?ping=1 requests which is the admin panel querying us for updates.)
 | 
					            # (Note that we purposely skip ...?ping=1 requests which is the admin
 | 
				
			||||||
 | 
					            # panel querying us for updates.)
 | 
				
			||||||
            # (Also, the URL changed in January 2016, but we'll accept both.)
 | 
					            # (Also, the URL changed in January 2016, but we'll accept both.)
 | 
				
			||||||
            m = re.match(rb"(?P<ip>\S+) - - \[(?P<date>.*?)\] \"GET /(bootstrap.sh|setup.sh) HTTP/.*\" 200 \d+ .* \"(?:curl|wget)", line, re.I)
 | 
					            m = re.match(rb"(?P<ip>\S+) - - \[(?P<date>.*?)\] \"GET /(bootstrap.sh|setup.sh) HTTP/.*\" 200 \d+ .* \"(?:curl|wget)", line, re.I)
 | 
				
			||||||
            if m:
 | 
					            if m:
 | 
				
			||||||
 | 
				
			|||||||
@ -3,10 +3,12 @@
 | 
				
			|||||||
# Generate documentation for how this machine works by
 | 
					# Generate documentation for how this machine works by
 | 
				
			||||||
# parsing our bash scripts!
 | 
					# parsing our bash scripts!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import cgi, re
 | 
					import cgi
 | 
				
			||||||
 | 
					import re
 | 
				
			||||||
import markdown
 | 
					import markdown
 | 
				
			||||||
from modgrammar import *
 | 
					from modgrammar import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def generate_documentation():
 | 
					def generate_documentation():
 | 
				
			||||||
    print("""<!DOCTYPE html>
 | 
					    print("""<!DOCTYPE html>
 | 
				
			||||||
<html>
 | 
					<html>
 | 
				
			||||||
@ -129,7 +131,8 @@ def generate_documentation():
 | 
				
			|||||||
            fn = parser.parse_string(line).filename()
 | 
					            fn = parser.parse_string(line).filename()
 | 
				
			||||||
        except:
 | 
					        except:
 | 
				
			||||||
            continue
 | 
					            continue
 | 
				
			||||||
		if fn in ("setup/start.sh", "setup/preflight.sh", "setup/questions.sh", "setup/firstuser.sh", "setup/management.sh"):
 | 
					        if fn in ("setup/start.sh", "setup/preflight.sh", "setup/questions.sh",
 | 
				
			||||||
 | 
					                  "setup/firstuser.sh", "setup/management.sh"):
 | 
				
			||||||
            continue
 | 
					            continue
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        import sys
 | 
					        import sys
 | 
				
			||||||
@ -151,11 +154,14 @@ def generate_documentation():
 | 
				
			|||||||
</html>
 | 
					</html>
 | 
				
			||||||
""")
 | 
					""")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HashBang(Grammar):
 | 
					class HashBang(Grammar):
 | 
				
			||||||
    grammar = (L('#!'), REST_OF_LINE, EOL)
 | 
					    grammar = (L('#!'), REST_OF_LINE, EOL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
        return ""
 | 
					        return ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def strip_indent(s):
 | 
					def strip_indent(s):
 | 
				
			||||||
    s = s.replace("\t", "    ")
 | 
					    s = s.replace("\t", "    ")
 | 
				
			||||||
    lines = s.split("\n")
 | 
					    lines = s.split("\n")
 | 
				
			||||||
@ -167,8 +173,10 @@ def strip_indent(s):
 | 
				
			|||||||
    lines = [line[min_indent:] for line in lines]
 | 
					    lines = [line[min_indent:] for line in lines]
 | 
				
			||||||
    return "\n".join(lines)
 | 
					    return "\n".join(lines)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Comment(Grammar):
 | 
					class Comment(Grammar):
 | 
				
			||||||
    grammar = ONE_OR_MORE(ZERO_OR_MORE(SPACE), L('#'), REST_OF_LINE, EOL)
 | 
					    grammar = ONE_OR_MORE(ZERO_OR_MORE(SPACE), L('#'), REST_OF_LINE, EOL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
        if self.string.replace("#", "").strip() == "":
 | 
					        if self.string.replace("#", "").strip() == "":
 | 
				
			||||||
            return "\n"
 | 
					            return "\n"
 | 
				
			||||||
@ -177,17 +185,24 @@ class Comment(Grammar):
 | 
				
			|||||||
        content = strip_indent(content)
 | 
					        content = strip_indent(content)
 | 
				
			||||||
        return markdown.markdown(content, output_format="html4") + "\n\n"
 | 
					        return markdown.markdown(content, output_format="html4") + "\n\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
FILENAME = WORD('a-z0-9-/.')
 | 
					FILENAME = WORD('a-z0-9-/.')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Source(Grammar):
 | 
					class Source(Grammar):
 | 
				
			||||||
    grammar = ((L('.') | L('source')), L(' '), FILENAME, Comment | EOL)
 | 
					    grammar = ((L('.') | L('source')), L(' '), FILENAME, Comment | EOL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def filename(self):
 | 
					    def filename(self):
 | 
				
			||||||
        return self[2].string.strip()
 | 
					        return self[2].string.strip()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
        return BashScript.parse(self.filename())
 | 
					        return BashScript.parse(self.filename())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CatEOF(Grammar):
 | 
					class CatEOF(Grammar):
 | 
				
			||||||
	grammar = (ZERO_OR_MORE(SPACE), L('cat '), L('>') | L('>>'), L(' '), ANY_EXCEPT(WHITESPACE), L(" <<"), OPTIONAL(SPACE), L("EOF"), EOL, REPEAT(ANY, greedy=False), EOL, L("EOF"), EOL)
 | 
					    grammar = (ZERO_OR_MORE(SPACE), L('cat '), L('>') | L('>>'), L(' '), ANY_EXCEPT(WHITESPACE),
 | 
				
			||||||
 | 
					               L(" <<"), OPTIONAL(SPACE), L("EOF"), EOL, REPEAT(ANY, greedy=False), EOL, L("EOF"), EOL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
        content = self[9].string
 | 
					        content = self[9].string
 | 
				
			||||||
        content = re.sub(r"\\([$])", r"\1", content)  # un-escape bash-escaped characters
 | 
					        content = re.sub(r"\\([$])", r"\1", content)  # un-escape bash-escaped characters
 | 
				
			||||||
@ -196,18 +211,23 @@ class CatEOF(Grammar):
 | 
				
			|||||||
               "overwrite" if ">>" not in self[2].string else "append to",
 | 
					               "overwrite" if ">>" not in self[2].string else "append to",
 | 
				
			||||||
               cgi.escape(content))
 | 
					               cgi.escape(content))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HideOutput(Grammar):
 | 
					class HideOutput(Grammar):
 | 
				
			||||||
    grammar = (L("hide_output "), REF("BashElement"))
 | 
					    grammar = (L("hide_output "), REF("BashElement"))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
        return self[1].value()
 | 
					        return self[1].value()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class EchoLine(Grammar):
 | 
					class EchoLine(Grammar):
 | 
				
			||||||
    grammar = (OPTIONAL(SPACE), L("echo "), REST_OF_LINE, EOL)
 | 
					    grammar = (OPTIONAL(SPACE), L("echo "), REST_OF_LINE, EOL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
        if "|" in self.string or ">" in self.string:
 | 
					        if "|" in self.string or ">" in self.string:
 | 
				
			||||||
            return "<pre class='shell'><div>" + recode_bash(self.string.strip()) + "</div></pre>\n"
 | 
					            return "<pre class='shell'><div>" + recode_bash(self.string.strip()) + "</div></pre>\n"
 | 
				
			||||||
        return ""
 | 
					        return ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class EditConf(Grammar):
 | 
					class EditConf(Grammar):
 | 
				
			||||||
    grammar = (
 | 
					    grammar = (
 | 
				
			||||||
        L('tools/editconf.py '),
 | 
					        L('tools/editconf.py '),
 | 
				
			||||||
@ -221,64 +241,99 @@ class EditConf(Grammar):
 | 
				
			|||||||
        OPTIONAL(SPACE),
 | 
					        OPTIONAL(SPACE),
 | 
				
			||||||
        EOL
 | 
					        EOL
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
        conffile = self[1]
 | 
					        conffile = self[1]
 | 
				
			||||||
        options = []
 | 
					        options = []
 | 
				
			||||||
        eq = "="
 | 
					        eq = "="
 | 
				
			||||||
		if self[3] and "-s" in self[3].string: eq = " "
 | 
					        if self[3] and "-s" in self[3].string:
 | 
				
			||||||
 | 
					            eq = " "
 | 
				
			||||||
        for opt in re.split("\s+", self[4].string):
 | 
					        for opt in re.split("\s+", self[4].string):
 | 
				
			||||||
            k, v = opt.split("=", 1)
 | 
					            k, v = opt.split("=", 1)
 | 
				
			||||||
            v = re.sub(r"\n+", "", fixup_tokens(v))  # not sure why newlines are getting doubled
 | 
					            v = re.sub(r"\n+", "", fixup_tokens(v))  # not sure why newlines are getting doubled
 | 
				
			||||||
            options.append("%s%s%s" % (k, eq, v))
 | 
					            options.append("%s%s%s" % (k, eq, v))
 | 
				
			||||||
		return "<div class='write-to'><div class='filename'>" + self[1].string + " <span>(change settings)</span></div><pre>" + "\n".join(cgi.escape(s) for s in options) + "</pre></div>\n"
 | 
					        return "<div class='write-to'><div class='filename'>" + self[1].string +
 | 
				
			||||||
 | 
					        " <span>(change settings)</span></div><pre>" +
 | 
				
			||||||
 | 
					        "\n".join(cgi.escape(s) for s in options) + "</pre></div>\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class CaptureOutput(Grammar):
 | 
					class CaptureOutput(Grammar):
 | 
				
			||||||
    grammar = OPTIONAL(SPACE), WORD("A-Za-z_"), L('=$('), REST_OF_LINE, L(")"), OPTIONAL(L(';')), EOL
 | 
					    grammar = OPTIONAL(SPACE), WORD("A-Za-z_"), L('=$('), REST_OF_LINE, L(")"), OPTIONAL(L(';')), EOL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
        cmd = self[3].string
 | 
					        cmd = self[3].string
 | 
				
			||||||
        cmd = cmd.replace("; ", "\n")
 | 
					        cmd = cmd.replace("; ", "\n")
 | 
				
			||||||
		return "<div class='write-to'><div class='filename'>$" + self[1].string + "=</div><pre>" + cgi.escape(cmd) + "</pre></div>\n"
 | 
					        return "<div class='write-to'><div class='filename'>$" +
 | 
				
			||||||
 | 
					        self[1].string + "=</div><pre>" + cgi.escape(cmd) + "</pre></div>\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SedReplace(Grammar):
 | 
					class SedReplace(Grammar):
 | 
				
			||||||
	grammar = OPTIONAL(SPACE), L('sed -i "s/'), OPTIONAL(L('^')), ONE_OR_MORE(WORD("-A-Za-z0-9 #=\\{};.*$_!()")), L('/'), ONE_OR_MORE(WORD("-A-Za-z0-9 #=\\{};.*$_!()")), L('/"'), SPACE, FILENAME, EOL
 | 
					    grammar = OPTIONAL(SPACE), L('sed -i "s/'), OPTIONAL(L('^')), \
 | 
				
			||||||
 | 
					        ONE_OR_MORE(WORD("-A-Za-z0-9 #=\\{};.*$_!()")), L('/'), \
 | 
				
			||||||
 | 
					        ONE_OR_MORE(WORD("-A-Za-z0-9 #=\\{};.*$_!()")), L('/"'), SPACE, FILENAME, EOL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
		return "<div class='write-to'><div class='filename'>edit<br>" + self[8].string + "</div><p>replace</p><pre>" + cgi.escape(self[3].string.replace(".*", ". . .")) + "</pre><p>with</p><pre>" + cgi.escape(self[5].string.replace("\\n", "\n").replace("\\t", "\t")) + "</pre></div>\n"
 | 
					        return "<div class='write-to'><div class='filename'>edit<br>" + self[8].string +
 | 
				
			||||||
 | 
					        "</div><p>replace</p><pre>" + cgi.escape(self[3].string.replace(".*", ". . .")) +
 | 
				
			||||||
 | 
					        "</pre><p>with</p><pre>" +
 | 
				
			||||||
 | 
					        cgi.escape(self[5].string.replace("\\n", "\n").replace("\\t", "\t")) + "</pre></div>\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class EchoPipe(Grammar):
 | 
					class EchoPipe(Grammar):
 | 
				
			||||||
    grammar = OPTIONAL(SPACE), L("echo "), REST_OF_LINE, L(' | '), REST_OF_LINE, EOL
 | 
					    grammar = OPTIONAL(SPACE), L("echo "), REST_OF_LINE, L(' | '), REST_OF_LINE, EOL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
        text = " ".join("\"%s\"" % s for s in self[2].string.split(" "))
 | 
					        text = " ".join("\"%s\"" % s for s in self[2].string.split(" "))
 | 
				
			||||||
		return "<pre class='shell'><div>echo " + recode_bash(text) + " \<br> | " + recode_bash(self[4].string) + "</div></pre>\n"
 | 
					        return "<pre class='shell'><div>echo " + recode_bash(text) +
 | 
				
			||||||
 | 
					        " \<br> | " + recode_bash(self[4].string) + "</div></pre>\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def shell_line(bash):
 | 
					def shell_line(bash):
 | 
				
			||||||
    return "<pre class='shell'><div>" + recode_bash(bash.strip()) + "</div></pre>\n"
 | 
					    return "<pre class='shell'><div>" + recode_bash(bash.strip()) + "</div></pre>\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AptGet(Grammar):
 | 
					class AptGet(Grammar):
 | 
				
			||||||
    grammar = (ZERO_OR_MORE(SPACE), L("apt_install "), REST_OF_LINE, EOL)
 | 
					    grammar = (ZERO_OR_MORE(SPACE), L("apt_install "), REST_OF_LINE, EOL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
        return shell_line("apt-get install -y " + re.sub(r"\s+", " ", self[2].string))
 | 
					        return shell_line("apt-get install -y " + re.sub(r"\s+", " ", self[2].string))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class UfwAllow(Grammar):
 | 
					class UfwAllow(Grammar):
 | 
				
			||||||
    grammar = (ZERO_OR_MORE(SPACE), L("ufw_allow "), REST_OF_LINE, EOL)
 | 
					    grammar = (ZERO_OR_MORE(SPACE), L("ufw_allow "), REST_OF_LINE, EOL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
        return shell_line("ufw allow " + self[2].string)
 | 
					        return shell_line("ufw allow " + self[2].string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RestartService(Grammar):
 | 
					class RestartService(Grammar):
 | 
				
			||||||
    grammar = (ZERO_OR_MORE(SPACE), L("restart_service "), REST_OF_LINE, EOL)
 | 
					    grammar = (ZERO_OR_MORE(SPACE), L("restart_service "), REST_OF_LINE, EOL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
        return shell_line("service " + self[2].string + " restart")
 | 
					        return shell_line("service " + self[2].string + " restart")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class OtherLine(Grammar):
 | 
					class OtherLine(Grammar):
 | 
				
			||||||
    grammar = (REST_OF_LINE, EOL)
 | 
					    grammar = (REST_OF_LINE, EOL)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
		if self.string.strip() == "": return ""
 | 
					        if self.string.strip() == "":
 | 
				
			||||||
		if "source setup/functions.sh" in self.string: return ""
 | 
					            return ""
 | 
				
			||||||
		if "source /etc/mailinabox.conf" in self.string: return ""
 | 
					        if "source setup/functions.sh" in self.string:
 | 
				
			||||||
 | 
					            return ""
 | 
				
			||||||
 | 
					        if "source /etc/mailinabox.conf" in self.string:
 | 
				
			||||||
 | 
					            return ""
 | 
				
			||||||
        return "<pre class='shell'><div>" + recode_bash(self.string.strip()) + "</div></pre>\n"
 | 
					        return "<pre class='shell'><div>" + recode_bash(self.string.strip()) + "</div></pre>\n"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BashElement(Grammar):
 | 
					class BashElement(Grammar):
 | 
				
			||||||
	grammar = Comment | CatEOF | EchoPipe | EchoLine | HideOutput | EditConf | SedReplace | AptGet | UfwAllow | RestartService | OtherLine
 | 
					    grammar = Comment | CatEOF | EchoPipe | EchoLine | HideOutput | EditConf | \
 | 
				
			||||||
 | 
					       SedReplace | AptGet | UfwAllow | RestartService | OtherLine
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
        return self[0].value()
 | 
					        return self[0].value()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Make some special characters to private use Unicode code points.
 | 
					# Make some special characters to private use Unicode code points.
 | 
				
			||||||
bash_special_characters1 = {
 | 
					bash_special_characters1 = {
 | 
				
			||||||
    "\n": "\uE000",
 | 
					    "\n": "\uE000",
 | 
				
			||||||
@ -292,6 +347,7 @@ bash_escapes = {
 | 
				
			|||||||
    "t": "\uE021",
 | 
					    "t": "\uE021",
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def quasitokenize(bashscript):
 | 
					def quasitokenize(bashscript):
 | 
				
			||||||
    # Make a parse of bash easier by making the tokenization easy.
 | 
					    # Make a parse of bash easier by making the tokenization easy.
 | 
				
			||||||
    newscript = ""
 | 
					    newscript = ""
 | 
				
			||||||
@ -366,6 +422,7 @@ def quasitokenize(bashscript):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    return newscript
 | 
					    return newscript
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def recode_bash(s):
 | 
					def recode_bash(s):
 | 
				
			||||||
    def requote(tok):
 | 
					    def requote(tok):
 | 
				
			||||||
        tok = tok.replace("\\", "\\\\")
 | 
					        tok = tok.replace("\\", "\\\\")
 | 
				
			||||||
@ -380,6 +437,7 @@ def recode_bash(s):
 | 
				
			|||||||
        return tok
 | 
					        return tok
 | 
				
			||||||
    return cgi.escape(" ".join(requote(tok) for tok in s.split(" ")))
 | 
					    return cgi.escape(" ".join(requote(tok) for tok in s.split(" ")))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def fixup_tokens(s):
 | 
					def fixup_tokens(s):
 | 
				
			||||||
    for c, enc in bash_special_characters1.items():
 | 
					    for c, enc in bash_special_characters1.items():
 | 
				
			||||||
        s = s.replace(enc, c)
 | 
					        s = s.replace(enc, c)
 | 
				
			||||||
@ -389,14 +447,17 @@ def fixup_tokens(s):
 | 
				
			|||||||
        s = s.replace(c, "\\" + esc)
 | 
					        s = s.replace(c, "\\" + esc)
 | 
				
			||||||
    return s
 | 
					    return s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BashScript(Grammar):
 | 
					class BashScript(Grammar):
 | 
				
			||||||
    grammar = (OPTIONAL(HashBang), REPEAT(BashElement))
 | 
					    grammar = (OPTIONAL(HashBang), REPEAT(BashElement))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def value(self):
 | 
					    def value(self):
 | 
				
			||||||
        return [line.value() for line in self[1]]
 | 
					        return [line.value() for line in self[1]]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @staticmethod
 | 
					    @staticmethod
 | 
				
			||||||
    def parse(fn):
 | 
					    def parse(fn):
 | 
				
			||||||
		if fn in ("setup/functions.sh", "/etc/mailinabox.conf"): return ""
 | 
					        if fn in ("setup/functions.sh", "/etc/mailinabox.conf"):
 | 
				
			||||||
 | 
					            return ""
 | 
				
			||||||
        string = open(fn).read()
 | 
					        string = open(fn).read()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # tokenize
 | 
					        # tokenize
 | 
				
			||||||
@ -408,7 +469,8 @@ class BashScript(Grammar):
 | 
				
			|||||||
        parser = BashScript.parser()
 | 
					        parser = BashScript.parser()
 | 
				
			||||||
        result = parser.parse_string(string)
 | 
					        result = parser.parse_string(string)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		v = "<div class='row'><div class='col-xs-12 sourcefile'>view the bash source for the following section at <a href=\"%s\">%s</a></div></div>\n" \
 | 
					        v = ("<div class='row'><div class='col-xs-12 sourcefile'>view the bash source for \
 | 
				
			||||||
 | 
					              the following section at <a href=\"%s\">%s</a></div></div>\n") \
 | 
				
			||||||
            % ("https://github.com/mail-in-a-box/mailinabox/tree/master/" + fn, fn)
 | 
					            % ("https://github.com/mail-in-a-box/mailinabox/tree/master/" + fn, fn)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        mode = 0
 | 
					        mode = 0
 | 
				
			||||||
@ -462,6 +524,7 @@ class BashScript(Grammar):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        return v
 | 
					        return v
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def wrap_lines(text, cols=60):
 | 
					def wrap_lines(text, cols=60):
 | 
				
			||||||
    ret = ""
 | 
					    ret = ""
 | 
				
			||||||
    words = re.split("(\s+)", text)
 | 
					    words = re.split("(\s+)", text)
 | 
				
			||||||
@ -471,10 +534,12 @@ def wrap_lines(text, cols=60):
 | 
				
			|||||||
            ret += " \\\n"
 | 
					            ret += " \\\n"
 | 
				
			||||||
            ret += "   "
 | 
					            ret += "   "
 | 
				
			||||||
            linelen = 0
 | 
					            linelen = 0
 | 
				
			||||||
		if linelen == 0 and w.strip() == "": continue
 | 
					        if linelen == 0 and w.strip() == "":
 | 
				
			||||||
 | 
					            continue
 | 
				
			||||||
        ret += w
 | 
					        ret += w
 | 
				
			||||||
        linelen += len(w)
 | 
					        linelen += len(w)
 | 
				
			||||||
    return ret
 | 
					    return ret
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
    generate_documentation()
 | 
					    generate_documentation()
 | 
				
			||||||
 | 
				
			|||||||
@ -4,17 +4,22 @@
 | 
				
			|||||||
# after updating the Bootstrap and jQuery <link> and <script> to compute the
 | 
					# after updating the Bootstrap and jQuery <link> and <script> to compute the
 | 
				
			||||||
# appropriate hash and insert it into the template.
 | 
					# appropriate hash and insert it into the template.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import re, urllib.request, hashlib, base64
 | 
					import re
 | 
				
			||||||
 | 
					import urllib.request
 | 
				
			||||||
 | 
					import hashlib
 | 
				
			||||||
 | 
					import base64
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn = "management/templates/index.html"
 | 
					fn = "management/templates/index.html"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
with open(fn, 'r') as f:
 | 
					with open(fn, 'r') as f:
 | 
				
			||||||
    content = f.read()
 | 
					    content = f.read()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def make_integrity(url):
 | 
					def make_integrity(url):
 | 
				
			||||||
    resource = urllib.request.urlopen(url).read()
 | 
					    resource = urllib.request.urlopen(url).read()
 | 
				
			||||||
    return "sha256-" + base64.b64encode(hashlib.sha256(resource).digest()).decode('ascii')
 | 
					    return "sha256-" + base64.b64encode(hashlib.sha256(resource).digest()).decode('ascii')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
content = re.sub(
 | 
					content = re.sub(
 | 
				
			||||||
    r'<(link rel="stylesheet" href|script src)="(.*?)" integrity="(.*?)"',
 | 
					    r'<(link rel="stylesheet" href|script src)="(.*?)" integrity="(.*?)"',
 | 
				
			||||||
    lambda m: '<' + m.group(1) + '="' + m.group(2) + '" integrity="' + make_integrity(m.group(2)) + '"',
 | 
					    lambda m: '<' + m.group(1) + '="' + m.group(2) + '" integrity="' + make_integrity(m.group(2)) + '"',
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
		Reference in New Issue
	
	Block a user