jaraco / irc

Full-featured Python IRC library for Python.
MIT License
390 stars 84 forks source link

push message from pipe using testbot.py #134

Closed 2Belette closed 6 years ago

2Belette commented 6 years ago

Hi,

I am trying to add a function to push message to IRC from pipe (mkfifo) but I have a basic issue I am unable to solve (I am not a python dev, just a beginner so trying my chance from here...)

class TestBot is running indefinitely and I need another function added to get message from pipe which needs to run under a while :

 def push_message(self):
    c = self.connection
    f=open(pipe,'r')
    print "Listening pipe"
    while True:
      time.sleep(1)
      line = f.read()
      if not line:
        continue
      print line[:-1]
      c.notice("nicktest", line)

The only way I found to run it is under a Thread (and also running TestBot under another Thread) like this:

class TestBot(irc.bot.SingleServerIRCBot):
  def __init__(self):
    conn = threading.Thread(target=self.run, args=(channel, nickname, server, port))
    conn.daemon = True
    conn.start()
    pipe = threading.Thread(target=self.push_message, args=())
   pipe.daemon = True
    pipe.start()

  def run(self, channel, nickname, server, port):
    irc.bot.SingleServerIRCBot.__init__(self, [(server, port)], nickname, nickname)

It is working fine, I got TestBot and my pipe function working BUT I am failing in the issue where my Threads are not sharing the variable between each-other so the last line from push_message is doing nothing as it is not using the connection done by TestBot.

Is there any trick I can use? Or if I am using Thread, could I call TestBot functions (notice here) ?

Many thanks if you have some ideas as I have tried this for hours and I am unable to find a working solution.

jaraco commented 6 years ago

The thread approach should be viable. Perhaps what's happening is you're essentially saving self.connection, but self.connection changes while waiting in the while loop. What happens if you instead replace c.notice with self.connection.notice?

Another approach you could take is to add an execute_every handler to your reactor that runs every second, attempts the read, and transmits any result.

2Belette commented 6 years ago

many thanks! I tried as well with self.connection.notice, no error but nothing :( :)

Would you mind if I send you my code ? it is very short and I am sure I am missing a very little piece to make it work..

Many thanks

jaraco commented 6 years ago

I'm afraid I can't help with your code in particular; I'm already overwhelmed by open source requests.

But here's how I would like to help - if you would put together a minimal example of an event handler, something that could be added to scripts/ to demonstrate how to handle asynchronous events in general, I could help iterate on that until we have a script that others like yourself could use as a template when they wish to accomplish the same thing as you.

You could submit that here, as a GitHub gist, or (preferably) as a pull request to this project.

Then, once we have a simple example working, that should provide you the context you need to solve the issues in your project.

How does that sound?

2Belette commented 6 years ago

Thanks, I will try to but not sure I will be able to create an event handler script as this is where I am effectively lost :) :(

if by chance you have any web site that can help me to understand and build this don't hesitate..

jaraco commented 6 years ago

I know the feeling. It's frustrating to be stuck on an effort with no avenues to progress. All I can suggest is to continue to dig into the code and troubleshoot. It's all there, mainly in the client module. Maybe read up on select and asynchronous network programming and threads. Unfortunately, I have little more to offer. Best of luck!