How should multiple parsers for keywords in strings be structured?

Viewed 49

I'm writing some code that parses strings, often using simple keywords. On parsing, the code performs various actions, such a printing a response, running functions etc. and it keeps track of whether it was able to respond.

I am actually using multiple parsers and have illustrated this in the code shown below.

What would be better ways to structure this code, particularly with a mind to scalability and code compactness? For example, imagine many more parsers being added that operate on principles more complex than simple keyword-spotting.

MWE:

#!/usr/bin/python

import json
import os
import requests
import subprocess
import sys

def main():

    message = "how are you"
    #message = "ip address"
    #message = "restart"

    triggered = [
        parse_1(message = message),
        parse_2(message = message)
    ]

    if not any(triggered):

        report_help()

def parse_1(
    message = None
    ):

    def keyphrases_text_response(
        message    = None,
        keyphrases = None,
        response   = None
        ):

        if any(pattern in message for pattern in keyphrases):

            print(response)

            return True

        else:

            return False

    triggered = [
        keyphrases_text_response(
            message    = message,
            keyphrases = [
                        "image"
                        ],
            response   = "http://i.imgur.com/MiqrlTh.jpg"
        ),
        keyphrases_text_response(
            message    = message,
            keyphrases = [
                        "sup",
                        "hi"
                        ],
            response   = "sup home bean"
        ),
        keyphrases_text_response(
            message    = message,
            keyphrases = [
                        "how are you",
                        "are you well",
                        "status"
                        ],
            response   = "nae bad fam"
        ),
        keyphrases_text_response(
            message    = message,
            keyphrases = [
                        "help",
                        "what can you do"
                        ],
            response   = "I can report my IP address and I can restart my script."
        )
    ]

    if any(triggered):

        return True

    else:

        return False

def parse_2(
    message = None
    ):

    triggered = []

    if any(pattern in message for pattern in\
        [
            "IP",
            "I.P.",
            "IP address",
            "I.P. address",
            "ip address"
        ]
        ):

        triggered.append(True)
        report_IP()

    if any(pattern in message for pattern in\
        [
            "restart"
        ]
        ):

        triggered.append(True)
        restart()

    if any(pattern in message for pattern in\
        [
            "SSH",
            "reverse"
        ]
        ):

        triggered.append(True)
        engage_command(
            command    = "ssh -R 10000:localhost:22 www.sern.ch",
            background = True
        )

    if any(triggered):

        return True

    else:

        return False

def report_IP(
    contact = None,
    country = True
    ):

    IP = "unknown"

    try:

        data_IP_website = requests.get("http://ipinfo.io/json")
        data_IP         = data_IP_website.json()
        IP              = data_IP["ip"]
        country         = data_IP["country"]

    except:

        pass

    text = "IP address: " + IP

    if country:

        text = text + " (" + country + ")"

    print(text)

def restart():

    print("restart! (and I'm in a crazy loop!)")
    import __main__
    os.execv(__main__.__file__, sys.argv)

def report_help():

    print("I can report my IP address, I can restart my script and I can run commands.")

def engage_command(
    command    = None,
    background = False
    ):

    print("engage command: {command}".format(command = command))

    if not background:

        process = subprocess.Popen(
            [command],
            shell      = True,
            executable = "/bin/bash"
        )
        process.wait()
        output, errors = process.communicate()

        return output

    else:

        subprocess.Popen(
            [command],
            shell      = True,
            executable = "/bin/bash"
        )

        return None

if __name__ == "__main__":

    main()
2 Answers
Related