Home > Back-end >  Add commands to user input
Add commands to user input

Time:05-13

Recently I started a project. My goal was it to have a script, which, once launched, could be able to control actions on the hosts computer if an instruction was send via email. (I wanted this so I could start tasks which take a long time to complete while I'm away from home)

I started programming and not long after I could send emails, recieve emails and analyze their content and take actions responding to the content in the email. The way I did it was like this: I first tried to use commands without a prefix but this caused errors so i added and "!" infront of every command which could be taken. Then I would split the contents of the email whenever there was a new line.

contents_of_the_email ="!screen\n!wait 5\n!hotkey alt tab\n"
# takes a screenshot waits 5 seconds and presses alt tab

lines = contents_of_the_email.count("\n")
contents_of_the_email = contents_of_the_email.split("\n")
for i in range(lines):
    if "!screen" in contents_of_the_email[i]:
        print("I took a screenshot and sent it to the specified email!")
    elif "!wait " in contents_of_the_email[i]:
        real = contents_of_the_email[i].split("!wait ")
        print(f"I slept for {real[1]} seconds!")
    elif "!hotkey " in contents_of_the_email[i]:
        real = contents_of_the_email[i].split(" ")
        print(f"I pressed the keys {real[1]} and {real[2]} at the same time!")

I replaced the actual code of the commands with print statements as they are not needed to understand my problem or recreate it.

Now this was getting very messy. I had added around 20 commands and they started conflicting. I mostly fixed it by changing the names of the commands but it was still spaghetti code.

I want to know if there is a more elegant way of adding commands to my program, I would desire something that works like this:

def takeScreenshot():
   print("I took a screenshot!")

addNewCommand(trigger="!screen",callback=takeScreenshot())

If this is possible in python I would really appreciate to know! Thank you :D

CodePudding user response:

You can try something like this:

def take_screenshot():
    print("I took a screenshot!")


def wait(sec):
    print(f"I waited for {sec} secs")


def hotkey(*args):
    print(f"I pressed the keys {', '.join(args)} at the same time")


def no_operation():
    print("Nothing")


FUNCTIONS = {
    '!wait': wait,
    '!screen': take_screenshot,
    '!hotkey': hotkey,
    '': no_operation
}


def call_command(command):
    function, *args = command.split(' ')
    FUNCTIONS[function](*args)


contents_of_the_email = "!screen\n!wait 5\n!hotkey alt tab\n"
# takes a screenshot waits 5 seconds and presses alt tab

for line in contents_of_the_email.split("\n"):
    call_command(line)

Just move funtions and dict definition to separate module.

CodePudding user response:

Have you considered using dictionaries to call your functions?

def run_A():
    print("A")
   # code...

def run_B():
    print("B")
   # code...

def run_C():
    print("C")
   # code...

inputDict = {'a': run_A, 'b': run_B, 'c': run_C}

# After running the above 
>>> inputDict['a']()
A

CodePudding user response:

Try using the built-in module cmd:

import cmd, time

class ComputerControl(cmd.Cmd):
    def do_screen(self, arg):
        pass # Screenshot
    def do_wait(self, length):
        time.sleep(float(length))
    def do_hotkey(self, arg):
        ...

inst = ComputerControl()
for line in contents_of_the_email.splitlines():
    line = line.lstrip("!")  # Remove the '!'
    inst.onecmd(line)
  • Related