2
\$\begingroup\$

After a bit of struggling I've come up with the code


import discord
import os
import subprocess as sub
import psutil

client = discord.Client()

my_path = os.getcwd()
program_instance = False
currently_installed = os.path.isdir("web-application")

def run_command(command):
    value = sub.Popen(command, stdout = sub.PIPE, stderr = sub.PIPE)
    return value.communicate()
    
def kill():
    global program_instance
    if not program_instance:
        return "Program instance not initiated";
    process = psutil.Process(program_instance.pid)
    for proc in process.children(recursive = True):
        proc.kill()
    process.kill()
    program_instance = False
    return "Instance Killed"

def delete_if_exists():
    global currently_installed
    kill()
    if currently_installed:
        os.system("rmdir /S /Q web-application")
        while currently_installed:
            currently_installed = os.path.isdir("web-application")


def download_from_git():
    #pull from git
    global currently_installed
    kill()
    delete_if_exists()
    instance = sub.Popen("git clone LINKTOWEBAPPLICATION")
    instance.communicate()
    currently_installed = True
    return "Successfully downloaded"
    
def run(download = False):
    global program_instance
    folders = run_command("dir")
    if not currently_installed or download:
        download_from_git()
    kill()
    path = my_path+"\\web-application"
    #installing values in pipenv
    install_command_instance = sub.Popen("pipenv install", cwd = path)
    install_command_instance.communicate()
    
    program_instance = sub.Popen("pipenv run app.py", cwd = path)
    return "App Running"

@client.event
async def on_ready():
    print("Gitty woke")



@client.event
async def on_message(message):
    if message.author.bot or not message.channel.id == MYDISCORDUSERID:
        return;
    command = message.content

    checker = lambda command_name: command == command_name

    if checker("run"):
        await message.channel.send(run())

    if checker("kill"):
        await message.channel.send(kill())

    if checker("download"):
        await message.channel.send(download_from_git())

    if checker("run download"):
        await message.channel.send(run(download = True))

    if checker("ping"):
        currently_installed = os.path.isdir("web-application")
        await message.channel.send("Running:" + f"\n{program_instance=}, {currently_installed=}")
        
with open(".key", "r") as key:
    client.run(key.read())

The biggest problem with this code was killing running processes. I just wanted to know if there are any easier ways to do this. And if I made any choices which are over complicated.

Edit: This bot is built to pull a repo from GitHub which contains a web-application that needs to be run. The reason I have to kill the application is so I can download a new version and rerun the code (as multiple instances of the website would be bad). The issue is that when the website is running I also have to be able to send the bot commands and thus have to run it as a separate instance so that the bot doesn't get "clogged" up running the site and can still take inputs

\$\endgroup\$
1
\$\begingroup\$

This depends on the nature and purpose of the process.

For example, you might schedule your process as a coroutine, and cancel its execution with Future.cancel: https://docs.python.org/3/library/asyncio-future.html#asyncio.Future.cancel

Your process killing method is aggressive and quite risky, some more context around why you're cancelling processes and the nature of the processes would be useful for providing answers.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.