Я использую модуль python ir c [1] и модуль pika в python для создания бота ir c, который прослушивает как сообщения канала, так и очередь rabbitmq.
Я взял исходный код из [2] и добавил к нему элементы pika:
#! /usr/bin/env python
#
# Example program using irc.client.
#
# This program is free without restrictions; do anything you like with
# it.
#
# Joel Rosdahl <joel@rosdahl.net>
import sys
import argparse
import itertools
import irc.client
import pika
target = "#test"
"The nick or channel to which to send messages"
def on_connect(connection, event):
if irc.client.is_channel(target):
connection.join(target)
return
main_loop(connection)
def on_join(connection, event):
main_loop(connection)
def get_lines():
while True:
yield sys.stdin.readline().strip()
def main_loop(connection):
for line in itertools.takewhile(bool, get_lines()):
print(line)
connection.privmsg(target, line)
connection.quit("Using irc.client.py")
def on_disconnect(connection, event):
raise SystemExit()
def get_args():
parser = argparse.ArgumentParser()
parser.add_argument('server')
parser.add_argument('nickname')
parser.add_argument('target', help="a nickname or channel")
parser.add_argument('-p', '--port', default=6667, type=int)
jaraco.logging.add_arguments(parser)
return parser.parse_args()
def callback(ch, method, properties, body):
print(" [x] Received %r" % body)
def get_channel():
creds = pika.PlainCredentials('testuser', 'testing')
params = pika.ConnectionParameters(
host="localhost",
virtual_host="/test",
credentials=creds)
connection = pika.BlockingConnection(params)
channel = connection.channel()
channel.queue_declare(queue='test')
channel.basic_consume(
queue='test', on_message_callback=callback, auto_ack=True)
return channel
def main():
chan = get_channel()
reactor = irc.client.Reactor()
try:
c = reactor.server().connect("irc.local", 6667, "testuser")
except irc.client.ServerConnectionError:
print(sys.exc_info()[1])
raise SystemExit(1)
c.add_global_handler("welcome", on_connect)
c.add_global_handler("join", on_join)
c.add_global_handler("disconnect", on_disconnect)
print("Processing reactor")
reactor.process_forever()
print("Channel : start consuming")
channel.start_consuming()
if __name__ == '__main__':
main()
Проблема с приведенным выше кодом в том, что я не изменил код get_lines (), чтобы фактически получить из очереди сообщений, так как я застрял с тем, на что его изменить.
Кроме того, строка «response.process_forever ()» блокирует строку «channel.start_consuming ()» и, очевидно, если я перемещаю канал .start_consuming () выше response.process_forever (), response.process_forever () не запускается.
На этом этапе я в тупике. Я думал об использовании многопроцессорных потоков; но мой опыт работы с потоками нулевой, и даже после прочтения [3] я не совсем уверен, что это поможет. Честно говоря, это смутило меня немного больше.
Я думал добавить обработчик обратного вызова on_ *, но поскольку все эти события основаны на ir c, обработчик не будет слушать очередь rabbitmq.
Может у кого-нибудь есть предложение, как одновременно запустить process_forever () l oop и цикл start_consuming (); то есть заставить бота прослушивать канал ir c и очередь сообщений?
Спасибо!
: ed
[1] - https://github.com/jaraco/irc
[2] - https://github.com/jaraco/irc/blob/master/scripts/irccat.py
[3] - https://realpython.com/intro-to-python-threading/