I am trying to use NiFi ExecuteScript to post messages to an irc chatroom using Python. Am I using the right syntax to pass a flowfile from a queue to the processor? Processor errors out with NameError: global name 'server' is not defined, but I am not positive what's causing it. Everything seems to work until I add the session.get().
import socket
from org.apache.nifi.processor.io import StreamCallback, InputStreamCallback
class PyStreamCallback(InputStreamCallback):
def __init__(self):
pass
self.ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.server = "irc.freenode.net"
self.channel = ""
self.botnick = ""
self.ircsock.connect((server, 6667))
self.ircsock.send(bytes("USER "+ botnick +" "+ botnick +" "+ botnick + " " + botnick + "\n"))
self.ircsock.send(bytes("NICK "+ botnick +"\n"))
def joinchan(self, chan):
self.ircsock.send(bytes("JOIN "+ chan +"\n"))
ircmsg = ""
while ircmsg.find("End of /NAMES list.") == -1:
self.ircmsg = ircsock.recv(2048)
self.ircmsg = ircmsg.strip('\n\r')
print(ircmsg)
def sendmsg(self, msg, target=channel):
self.ircsock.send(bytes("PRIVMSG "+ target +" :"+ msg +"\n"))
flowFile = session.get()
if (flowFile != None):
flowFile = session.read(flowFile,PyStreamCallback())
session.commit()
self.ircsock.connect((server, 6667))
should be
self.ircsock.connect((self.server, 6667))
Related
I am trying to make my IRC bot handle multiple messages at a time, but it's not sending back messages.
Behavior: Process(target=func) is called, func() calls a function that has socket.socket().send(message) in it, but the message doesn't send. Suspect is that the socket isn't passed to the sending function.
Code:
import socket
import re
import requests
import urllib
import config # just my file of variables
import math
import time
import sys
import winsound
import string
import random
import multiprocessing
# import traceback
# CONNECTION COMMANDS
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server = config.server # Server
password = config.password # Password
botnick = config.botnick # Your bots nick
adminname = config.adminname # Your IRC nickname
exitcode = config.exitcode
ircsock.settimeout(300)
def connection(host, port, password, nick, realname):
ircsock.connect((host, port))
ircsock.send(bytes("PASS " + password + "\n", "UTF-8"))
ircsock.send(bytes("USER " + botnick + " " + botnick + " " + botnick + " " + botnick + "\n", "UTF-8"))
ircsock.send(bytes("NICK " + botnick + "\n", "UTF-8"))
def ping(): # respond to server Pings.
ircsock.send(bytes("PONG :pingis\n", "UTF-8"))
print("Ponged after " + str(time.time() - last_ping) + " seconds from last ping!")
def sendmsg(msg, target): # sends messages to the target.
# it enters here, no problem
ircsock.send(bytes("PRIVMSG " + target + " :" + msg + "\n", "UTF-8")) ### At this point, when using multiprocessing, the bot fails ###
print("Sending: [" + str(msg) + "] to: " + str(target))
# MAIN
if __name__ == '__main__':
connection(server, 6667, password, botnick, botnick)
# joinchan(channel)
while 1:
# print("Connected!")
ircmsg = ircsock.recv(1024).decode("UTF-8")
ircmsg = ircmsg.strip('\n\r')
if ircmsg.find("PRIVMSG") != -1:
try:
# “:[Nick]!~[hostname]#[IP Address] PRIVMSG [channel] :[message]”
name = ircmsg.split('PRIVMSG', 1)[0].split(':')[-1].split("!")[0] # ircmsg.split('!', 1)[0][1:]
message = ircmsg.split('PRIVMSG', 1)[1].split(':', 1)[1].splitlines()[0] # .strip()[0]
me = ircmsg.split('PRIVMSG', 1)[1].split(':', 1)[0].split()[0]
# print(me)
print("name: " + name + ", message: " + message)
if len(name) < 17:
if me == botnick:
if message.find("Hi!") != -1:
process1 = multiprocessing.Process(target=sendmsg, args=("Hello!", name))
process1.daemon = True
process1.start()
if name.lower() == adminname.lower() and message.rstrip() == exitcode:
sendmsg("Bot is quitting.", name)
ircsock.send(bytes("QUIT \n", "UTF-8"))
sys.exit()
time.sleep(1)
except:
pass
elif ircmsg.find("PING") != -1:
ping()
Please word your answers as simply as possible, since I am not that experienced in Python. The code above can be run with a correct config.py file.
Format:
password = "" # password to open the server
exitcode = "" # What is typed to stop the bot
server = "" # Server
botnick = "" # Your bots nick
adminname = "" # Your IRC nickname
I wrote a simple Python twitch bot following a video tutorial, but the tutorial didn't include whisper functionality. It can currently connect to the chat of the channel I specify, but when I try to have it send a whisper nothing happens. Here's the relevant code bits:
import socket
def openSocket():
s = socket.socket()
s.connect((HOST, PORT))
message = "PASS " + PASS + "\r\n"
s.send(message.encode('utf-8'))
message = "NICK " + USER + "\r\n"
s.send(message.encode('utf-8'))
message = "JOIN #" + CHAN + "\r\n"
s.send(message.encode('utf-8'))
return s
def sendMessage(s, message):
messageTemp = "PRIVMSG #" + CHAN + " :" + message + "\r\n"
s.send(messageTemp.encode('utf-8'))
print("Sent:" + messageTemp)
def sendWhisper(s, user, message):
messageTemp = "PRIVMSG #jtv :/w " + user + " " + message
s.send(messageTemp.encode('utf-8'))
import string
from Socket import sendMessage
def joinRoom(s):
readbuffer = ""
Loading = True
while Loading:
readbuffer = readbuffer + s.recv(1024).decode()
temp = readbuffer.split('\n')
readbuffer = temp.pop()
for line in temp:
print(line)
Loading = loadingComplete(line)
def loadingComplete(line):
if("End of /NAMES list" in line):
return False;
else: return True
I've been reading a little bit about connecting to some sort of group chat in order to make this work, but I'm confused and haven't found what I'm looking for. It seems like it should be an easy fix. Any help is appreciated.
You were very close. Where you messed up is there should not be a # in front of jtv:
def sendWhisper(s, user, message):
messageTemp = "PRIVMSG jtv :/w " + user + " " + message
s.send(messageTemp.encode('utf-8'))
So the following site explains how to make an irc bot, using socket, but it only works for python2, so I tried to make it compatible, but I get the error mentioned in the title.
Here is my code:
import socket
# Some basic variables used to configure the bot
server = "irc.freenode.net" # Server
channel = "#volafile"
botnick = "Mybot" # Your bots nick
def ping(): # This is our first function! It will respond to server Pings.
ircsock.send(b"PONG :pingis\n")
def sendmsg(chan , msg): # to the channel.
ircsock.send(b"PRIVMSG "+ chan +b" :"+ msg +b"\n")
def joinchan(chan): # This function is used to join channels.
ircsock.send(b"JOIN "+ chan + b"\n")
def hello(): # This function responds to a user that inputs "Hello Mybot"
ircsock.send(b"PRIVMSG "+ channel + b" :Hello!\n")
ircsock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
ircsock.connect((server, 6667)) # Here we connect to the server using the port 6667
ircsock.send(b"USER "+ botnick + b" "+ botnick + b" "+ botnick + b" :This bot is a result of a tutoral covered on http://shellium.org/wiki.\n") # user authentication
ircsock.send(b"NICK "+ botnick + b"\n") # here we actually assign the nick to the bot
joinchan(channel) # Join the channel using the functions we previously defined
while 1: # Be careful with these! it might send you to an infinite loop
ircmsg = ircsock.recv(2048) # receive data from the server
ircmsg = ircmsg.strip(b'\n\r') # removing any unnecessary linebreaks.
print(ircmsg) # Here we print what's coming from the server
if ircmsg.find(b":Hello "+ botnick) != -1:
hello()
if ircmsg.find(b"PING :") != -1: # if the server pings us then we've got to respond!
ping()
The error message:
Traceback (most recent call last):
File "irctest.py", line 23, in <module>
ircsock.send(b"USER "+ botnick + b" "+ botnick + b" "+ botnick + b" :This botis a result of a tutoral covered on http://shellium.org/wiki.\n") # user authentication
TypeError: can't concat bytes to str
botnick is not a bytes value but a string:
botnick = "Mybot"
Make that a bytes literal by adding a b in front:
botnick = b"Mybot"
Here I try to get as much information about the server instance.
#! C:\python34\python
import sys
from http.server import SimpleHTTPRequestHandler
from http.server import HTTPServer
if sys.argv[1:]: port = int(sys.argv[1])
else: port = 8000
def expl(H):
R = ''
for item in H:
R += "<br/> -> " + str(item) +" :"+ str(H[item])
return R
class MyHandler(SimpleHTTPRequestHandler):
def __init__(self,req,client_addr,server):
SimpleHTTPRequestHandler.__init__(self,req,client_addr,server)
def do_GET(self):
page_text = ""\
+ "server_version: "+ self.server_version +"<br/>"\
+ "sys_version: "+ self.sys_version +"<br/>"\
+ "protocol_version: "+ self.protocol_version +"<br/>"\
+ "version_string(): "+ str(self.version_string()) +"<br/>"\
+ "address_string(): "+ self.address_string() +"<br/>"\
+ "path: "+ self.path +"<br/>"\
+ "command: "+ self.command +"<br/>"\
+ "headers: "+ expl(self.headers) +"<br/>"\
+ "server.server_name: "+ self.server.server_name +"<br/>"\
+ "server.server_port: "+ str(self.server.server_port) +"<br/>"\
+ "server.socket.getsockname(): "+ str(self.server.socket.getsockname()) +"<br/>"\
+ "responses: "+ expl(self.responses) +"<br/>"
#Err + self.client_address +"<br/>"\
#Err + str(self.headers.getheaders('referer')) +"<br/>"\
self.send_response(200)
self.send_header("Content-type", "text/html")
self.send_header("Content-length", len( page_text ))
self.end_headers()
self.wfile.write( page_text.encode("utf-8") )
try:
server_address = ('localhost', port)
httpd = HTTPServer(server_address, MyHandler)
sa = httpd.socket.getsockname()
print("Serving HTTP on", sa[0], "port", sa[1], "...")
httpd.serve_forever()
except KeyboardInterrupt:
print('^C received, shutting down server')
httpd.socket.close()
On the browser, you can use those URL:
localhost:8000/
localhost:8000/foo.html
But not:
sub.localhost:8000/
I think the server doesn't listen any subdomain ?
Even if I try to change this:
server_address = ('localhost', port)
to
server_address = ('sub.localhost', port)
Does someone know how to listen a subdomain with python ?
I am trying to implement a simple threaded SocketServer (using SocketServer.ThreadedMixIn). However, my server stops receiving further messages. Here is the code:
#!/usr/bin/python -u
import SocketServer
import sys
class MYAgentHandler(SocketServer.BaseRequestHandler):
def handle(self):
try:
data = self.request.recv(1024)
print "Received request " + str(data) + "\n"
reply = str(agent.processAgentMessage(data))
self.request.send(reply)
self.request.close()
except Exception, instr:
print "While processing data " + data + " error encountered " + str(instr) + "\n"
class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
daemon_threads = True
allow_reuse_address = True
def __init__(self, server_address, RequestHandlerClass):
SocketServer.TCPServer.__init__(self, server_address, RequestHandlerClass)
class MYAgent:
def processAgentMessage(self, msg):
try:
tokens = msg.split('^')
if tokens[0] == "CreateSession":
return("New session")
elif tokens[0] == "GetStatus":
return("Init")
except Exception, instr:
print "Error while processing message " + str(instr) + "\n"
agent = MYAgent()
def main():
MYServer = sys.argv[1]
MYAgentPort = sys.argv[2]
agent.listener = ThreadedTCPServer((MYServer, int(MYAgentPort)), MYAgentHandler)
agent.listener.serve_forever()
if __name__ == '__main__':
main()
And here is my client:
#!/usr/bin/python -u
import socket
import time
if __name__ == "__main__":
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.connect(('localhost', 15222))
try:
sock.send("CreateSession")
sessionID = str(sock.recv(1024))
print "Received: " + sessionID
sock.send("GetStatus^"+sessionID)
print "Sent Getstatus\n"
time.sleep(1)
response = str(sock.recv(1024))
print "status of " + str(sessionID) + " is " + str(response) + "\n"
sock.close()
except Exception, instr:
print "Error occurred " + str(instr) + "\n"
Here is one session. Server output:
$ ./t.py localhost 15222
Received request CreateSession
Client output:
$ ./client.py
Received: New session
Sent Getstatus
status of New session is
$
Any ideas why this is happening?
You have to remove self.request.close() (which closes the connection) and wrap everything with while True: (so it will continue to read from the same socket).