0

I am coding a discord bot with python, I am running into difficulties with the next feature. When the message: ('user' joined) is read the bot should start looping the function every x seconds until the message: ('user' left) is read.

I have been testing different code in scratch files. It succesfully starts looping at 'user' joined. But when the ('user' left) message should come through it won't take the new argument and continues the loop forever.

These two versions look most promising:

import re
import time



def message(servermessage):
    a = re.sub("[^\S]", " ", servermessage).split()
    if a[1] == 'joined':
        online = False

    elif a[1] == 'left':
        online = True

    while True:
        mcusername = a[0]
        print(mcusername, 0)
        if online:
            break
        time.sleep(2)



message('user joined')
time.sleep(10)
message('user left')

and

import re
import sched, time

s = sched.scheduler(time.time, time.sleep)

def message(servermessage):
    a = re.sub("[^\S]", " ", servermessage).split()
    def rewardplayer():
        s.enter(1, 1, rewardplayer)
        mcusername = a[0]
        print(mcusername, 0)
    if a[1] == 'joined':
        s.enter(1, 1, rewardplayer)
        s.run()

    elif a[1] == 'left':
        s.cancel()


message('user joined')
time.sleep(10)
print('done')
message('user left')


Another requirement that I have is that it should be able to run the same loop for a different user when a ('newuser' joined) message is given before the ('previoususer' left) message from a previous user.

I apologise for the vague explanation. But I hope you can help. Thanks in advance!

justTJ
  • 1
  • 1

1 Answers1

0

About your first code: there you have while which should be broken when online is True. But its never changing inside that loop. So its similar to deadlock.

About your second code: there you are using "scheduler". Usually it means you want to run some events periodically. But your aim is to react when event was happened. In any time. Not schedulled.

So here I can recommend you to use async python way. (please, read about asyncio)

import re
import asyncio


async def process_msgs(queue):
    while True:
        msg = await queue.get()
        online, usr_name = parse_msg(msg)
        print(usr_name, 0)
        queue.task_done()


def parse_msg(msg):
    result = re.sub("[^\S]", " ", msg).split()
    action = result[1]
    usr_name = result[0]
    if action == 'joined':
        online = False
    elif action == 'left':
        online = True
    return online, usr_name


async def main():
    queue = asyncio.Queue()
    queue.put_nowait('usr joined')
    task = asyncio.create_task(process_msgs(queue))
    queue.put_nowait('usr left')
    await queue.join()
    task.cancel()

asyncio.run(main())

You can use it like that. There we have a queue, where we put our events. You can do that through infinite way too (listen socket or smthg - here you will get msg about different users).

And we have task (worker), which work while our "main" function is alive.

Jefferson Houp
  • 858
  • 1
  • 7
  • 17
  • Thank you for your answer. I tested a lot with this code but I couldn't get it to work how I wanted it. Later I found another solution to achieve the needed result. Still I think the queue function will come in handy and I thank you for showing it to me! Kind regards. – justTJ Jun 19 '21 at 21:11