New version of nemuspeak with class and xml configuration file
Bonus: fix exception when empty message received
This commit is contained in:
parent
dc9965b0c9
commit
81342acd0c
210
nemuspeak.py
210
nemuspeak.py
@ -9,56 +9,53 @@ import re
|
|||||||
import subprocess
|
import subprocess
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
from xml.dom.minidom import parse
|
||||||
import thread
|
import thread
|
||||||
|
|
||||||
if len(sys.argv) < 3:
|
if len(sys.argv) == 1:
|
||||||
print "This script takes at least 2 args: server port [channel [channel [...]]]"
|
print "This script takes exactly 1 arg: a XML config file"
|
||||||
sys.exit(0)
|
sys.exit(1)
|
||||||
|
|
||||||
#HOST='192.168.0.242'
|
SERVER = list()
|
||||||
#HOST = 'nemunai.re'
|
SMILEY = list()
|
||||||
#PORT = 2778
|
g_queue = list()
|
||||||
HOST = sys.argv[1]
|
|
||||||
PORT = int(sys.argv[2])
|
|
||||||
#HOST = 'irc.rezosup.org'
|
|
||||||
#PORT = 6667
|
|
||||||
NICK = 'nemunaire'
|
|
||||||
IDENT = 'nemuspeak'
|
|
||||||
REALNAME = 'nemubot speaker'
|
|
||||||
OWNER = 'nemunaire' #The bot owner's nick
|
|
||||||
#CHANLIST = ['#42sh', '#korteam']
|
|
||||||
CHANLIST = []
|
|
||||||
if len(sys.argv) > 3:
|
|
||||||
for i in range(3, len(sys.argv)):
|
|
||||||
CHANLIST.append(sys.argv[i])
|
|
||||||
readbuffer = '' #Here we store all the messages from server
|
|
||||||
|
|
||||||
queue = []
|
|
||||||
talkEC = 0
|
talkEC = 0
|
||||||
stopSpk = 0
|
stopSpk = 0
|
||||||
lastmsg = []
|
lastmsg = []
|
||||||
|
|
||||||
s = socket.socket( ) #Create the socket
|
dom = parse(sys.argv[1])
|
||||||
s.connect((HOST, PORT)) #Connect to server
|
|
||||||
s.send("PASS %s\r\n" % "McsuapTesbuf")
|
|
||||||
s.send("NICK %s\r\n" % NICK)
|
|
||||||
s.send("USER %s %s bla :%s\r\n" % (IDENT, HOST, REALNAME))
|
|
||||||
#s.send("JOIN %s\r\n" % CHANLIST)
|
|
||||||
|
|
||||||
print("Welcome on Nemubot speaker. I operate on %s. My PID is %i" % (CHANLIST, os.getpid()))
|
config = dom.getElementsByTagName('config')[0]
|
||||||
|
|
||||||
|
if config.hasAttribute("nick"):
|
||||||
|
NICK = config.getAttribute("nick")
|
||||||
|
else:
|
||||||
|
NICK = "bot"
|
||||||
|
if config.hasAttribute("owner"):
|
||||||
|
OWNER = config.getAttribute("owner")
|
||||||
|
else:
|
||||||
|
OWNER = " "
|
||||||
|
if config.hasAttribute("realname"):
|
||||||
|
REALNAME = config.getAttribute("realname")
|
||||||
|
else:
|
||||||
|
REALNAME = OWNER + "'s bot"
|
||||||
|
|
||||||
|
for smiley in config.getElementsByTagName('smiley'):
|
||||||
|
if smiley.hasAttribute("txt") and smiley.hasAttribute("mood"):
|
||||||
|
SMILEY.append((smiley.getAttribute("txt"), smiley.getAttribute("mood")))
|
||||||
|
print ("%d smileys loaded"%len(SMILEY))
|
||||||
|
|
||||||
def speak(endstate):
|
def speak(endstate):
|
||||||
global lastmsg, queue, talkEC, stopSpk
|
global lastmsg, g_queue, talkEC, stopSpk
|
||||||
talkEC = 1
|
talkEC = 1
|
||||||
stopSpk = 0
|
stopSpk = 0
|
||||||
|
|
||||||
if len(lastmsg) < 1:
|
if len(lastmsg) < 1:
|
||||||
lastmsg = queue.pop(0)
|
lastmsg = g_queue.pop(0)
|
||||||
|
|
||||||
while not stopSpk and len(queue) > 0:
|
while not stopSpk and len(g_queue) > 0:
|
||||||
msg = queue.pop(0)
|
msg = g_queue.pop(0)
|
||||||
lang = "fr"
|
lang = "fr"
|
||||||
|
|
||||||
sentence = ""
|
sentence = ""
|
||||||
force = 0
|
force = 0
|
||||||
|
|
||||||
@ -73,55 +70,19 @@ def speak(endstate):
|
|||||||
sentence += "Sur " + msg[0] + ". "
|
sentence += "Sur " + msg[0] + ". "
|
||||||
force = 1
|
force = 1
|
||||||
|
|
||||||
|
action = 0
|
||||||
if msg[3].find("ACTION ") == 1:
|
if msg[3].find("ACTION ") == 1:
|
||||||
sentence += msg[1] + " "
|
sentence += msg[1] + " "
|
||||||
msg[3] = msg[3].replace("ACTION ", "")
|
msg[3] = msg[3].replace("ACTION ", "")
|
||||||
elif msg[3].find(":)") >= 0:
|
action = 1
|
||||||
sentence += msg[1] + " sourit : "
|
for (txt, mood) in SMILEY:
|
||||||
msg[3] = msg[3].replace(":)", "")
|
if msg[3].find(txt) >= 1:
|
||||||
elif msg[3].find(";)") >= 0:
|
sentence += msg[1] + " %s : "%mood
|
||||||
sentence += msg[1] + " fait un clin d'oeil : "
|
msg[3] = msg[3].replace(txt, "")
|
||||||
msg[3] = msg[3].replace(";)", "")
|
action = 1
|
||||||
elif msg[3].find(":(") >= 0:
|
break
|
||||||
sentence += msg[1] + " est triste : "
|
|
||||||
msg[3] = msg[3].replace(":(", "")
|
|
||||||
elif msg[3].find("<3") >= 0:
|
|
||||||
sentence += msg[1] + " aime : "
|
|
||||||
msg[3] = msg[3].replace("<3", "")
|
|
||||||
elif msg[3].find(":'(") >= 0 or msg[3].find(";(") >= 0:
|
|
||||||
sentence += msg[1] + " pleure : "
|
|
||||||
msg[3] = msg[3].replace(":'(", "")
|
|
||||||
msg[3] = msg[3].replace(";(", "")
|
|
||||||
elif msg[3].find(":D") >= 0 or msg[3].find(":d") >= 0:
|
|
||||||
sentence += msg[1] + " rit : "
|
|
||||||
msg[3] = msg[3].replace(":D", "")
|
|
||||||
msg[3] = msg[3].replace(":d", "")
|
|
||||||
elif msg[3].find(":P") >= 0 or msg[3].find(":p") >= 0:
|
|
||||||
sentence += msg[1] + " tire la langue : "
|
|
||||||
msg[3] = msg[3].replace(":P", "")
|
|
||||||
msg[3] = msg[3].replace(":p", "")
|
|
||||||
elif msg[3].find(":S") >= 0 or msg[3].find(":s") >= 0:
|
|
||||||
sentence += msg[1] + " est embarassé : "
|
|
||||||
msg[3] = msg[3].replace(":S", "")
|
|
||||||
msg[3] = msg[3].replace(":s", "")
|
|
||||||
elif msg[3].find("XD") >= 0 or msg[3].find("xd") >= 0 or msg[3].find("xD") >= 0 or msg[3].find("Xd") >= 0 or msg[3].find("X)") >= 0 or msg[3].find("x)") >= 0:
|
|
||||||
sentence += msg[1] + " se marre : "
|
|
||||||
msg[3] = msg[3].replace("xd", "")
|
|
||||||
msg[3] = msg[3].replace("XD", "")
|
|
||||||
msg[3] = msg[3].replace("Xd", "")
|
|
||||||
msg[3] = msg[3].replace("xD", "")
|
|
||||||
msg[3] = msg[3].replace("X)", "")
|
|
||||||
msg[3] = msg[3].replace("x)", "")
|
|
||||||
elif msg[3].find("\\o/") >= 0 or msg[3].find("\\O/") >= 0:
|
|
||||||
sentence += msg[1] + " fait une accolade : "
|
|
||||||
msg[3] = msg[3].replace("\\o/", "")
|
|
||||||
msg[3] = msg[3].replace("\\O/", "")
|
|
||||||
elif msg[3].find("/o/") >= 0 or msg[3].find("\\o\\") >= 0:
|
|
||||||
sentence += msg[1] + " danse : "
|
|
||||||
msg[3] = msg[3].replace("/o/", "")
|
|
||||||
msg[3] = msg[3].replace("\\o\\", "")
|
|
||||||
|
|
||||||
elif force or msg[1] != lastmsg[1]:
|
if action == 0 and (force or msg[1] != lastmsg[1]):
|
||||||
sentence += msg[1] + " dit : "
|
sentence += msg[1] + " dit : "
|
||||||
|
|
||||||
if re.match(".*(https?://)?(www\\.)?ycc.fr/[a-z0-9A-Z]+.*", msg[3]) is not None:
|
if re.match(".*(https?://)?(www\\.)?ycc.fr/[a-z0-9A-Z]+.*", msg[3]) is not None:
|
||||||
@ -132,14 +93,16 @@ def speak(endstate):
|
|||||||
|
|
||||||
if re.match("^ *[^a-zA-Z0-9 ][a-zA-Z]{2}[^a-zA-Z0-9 ]", msg[3]) is not None:
|
if re.match("^ *[^a-zA-Z0-9 ][a-zA-Z]{2}[^a-zA-Z0-9 ]", msg[3]) is not None:
|
||||||
if sentence != "":
|
if sentence != "":
|
||||||
subprocess.call(["espeak", "-v", "fr", sentence])
|
intro = subprocess.call(["espeak", "-v", "fr", sentence])
|
||||||
|
#intro.wait()
|
||||||
|
|
||||||
lang = msg[3][1:3].lower()
|
lang = msg[3][1:3].lower()
|
||||||
sentence = msg[3][4:]
|
sentence = msg[3][4:]
|
||||||
else:
|
else:
|
||||||
sentence += msg[3]
|
sentence += msg[3]
|
||||||
|
|
||||||
subprocess.call(["espeak", "-v", lang, sentence])
|
spk = subprocess.call(["espeak", "-v", lang, sentence])
|
||||||
|
#spk.wait()
|
||||||
|
|
||||||
lastmsg = msg
|
lastmsg = msg
|
||||||
|
|
||||||
@ -149,13 +112,17 @@ def speak(endstate):
|
|||||||
talkEC = 1
|
talkEC = 1
|
||||||
|
|
||||||
|
|
||||||
def parsemsg(msg):
|
def parsemsg (msg, CHANLIST):
|
||||||
global talkEC, stopSpk, queue
|
global g_queue, NICK, stopSpk, talkEC
|
||||||
complete = msg[1:].split(':',1) #Parse the message into useful data
|
complete = msg[1:].split(':',1) #Parse the message into useful data
|
||||||
info = complete[0].split(' ')
|
info = complete[0].split(' ')
|
||||||
msgpart = complete[1]
|
msgpart = complete[1]
|
||||||
sender = info[0].split('!')
|
sender = info[0].split('!')
|
||||||
|
|
||||||
|
#Skip on empty content
|
||||||
|
if len(msgpart) <= 0:
|
||||||
|
return
|
||||||
|
|
||||||
#Bad format, try to fix that
|
#Bad format, try to fix that
|
||||||
if len(info) == 1:
|
if len(info) == 1:
|
||||||
pv = msg.index(" ", msg.index("PRIVMSG") + 9)
|
pv = msg.index(" ", msg.index("PRIVMSG") + 9)
|
||||||
@ -179,14 +146,17 @@ def parsemsg(msg):
|
|||||||
thread.start_new_thread(speak, (0,))
|
thread.start_new_thread(speak, (0,))
|
||||||
|
|
||||||
elif cmd[0] == 'reset':
|
elif cmd[0] == 'reset':
|
||||||
while len(queue) > 0:
|
while len(g_queue) > 0:
|
||||||
queue.pop()
|
g_queue.pop()
|
||||||
|
|
||||||
elif cmd[0] == 'save':
|
elif cmd[0] == 'save':
|
||||||
if talkEC == 0:
|
if talkEC == 0:
|
||||||
talkEC = 1
|
talkEC = 1
|
||||||
stopSpk = 1
|
stopSpk = 1
|
||||||
|
|
||||||
|
elif cmd[0] == 'test':
|
||||||
|
parsemsg(":Quelqun!someone@p0m.fr PRIVMSG %s :Ceci est un message de test ;)"%(CHANLIST[0]), CHANLIST)
|
||||||
|
|
||||||
elif cmd[0] == 'list':
|
elif cmd[0] == 'list':
|
||||||
print "Currently listened channels:"
|
print "Currently listened channels:"
|
||||||
for chan in CHANLIST:
|
for chan in CHANLIST:
|
||||||
@ -205,27 +175,67 @@ def parsemsg(msg):
|
|||||||
print cmd[1] + " not in listened channels"
|
print cmd[1] + " not in listened channels"
|
||||||
|
|
||||||
elif sender[0] != OWNER and (len(CHANLIST) == 0 or CHANLIST.count(info[2]) > 0 or info[2] == NICK):
|
elif sender[0] != OWNER and (len(CHANLIST) == 0 or CHANLIST.count(info[2]) > 0 or info[2] == NICK):
|
||||||
queue.append([info[2], sender[0], datetime.now(), msgpart])
|
g_queue.append([info[2], sender[0], datetime.now(), msgpart])
|
||||||
if talkEC == 0:
|
if talkEC == 0:
|
||||||
thread.start_new_thread(speak, (0,))
|
thread.start_new_thread(speak, (0,))
|
||||||
|
|
||||||
|
|
||||||
def read():
|
class Server:
|
||||||
global s, readbuffer
|
def __init__(self, server):
|
||||||
while 1:
|
if server.hasAttribute("server"):
|
||||||
readbuffer = readbuffer + s.recv(1024) #recieve server messages
|
self.host = server.getAttribute("server")
|
||||||
temp = readbuffer.split("\n")
|
else:
|
||||||
readbuffer = temp.pop( )
|
self.host = "localhost"
|
||||||
|
if server.hasAttribute("port"):
|
||||||
|
self.port = int(server.getAttribute("port"))
|
||||||
|
else:
|
||||||
|
self.port = 6667
|
||||||
|
if server.hasAttribute("password"):
|
||||||
|
self.password = server.getAttribute("password")
|
||||||
|
else:
|
||||||
|
self.password = None
|
||||||
|
|
||||||
for line in temp:
|
self.channels = list()
|
||||||
line = line.rstrip() #remove trailing 'rn'
|
for channel in server.getElementsByTagName('channel'):
|
||||||
|
self.channels.append(channel.getAttribute("name"))
|
||||||
|
|
||||||
if line.find('PRIVMSG') != -1: #Call a parsing function
|
def launch(self):
|
||||||
parsemsg(line)
|
thread.start_new_thread(self.connect, ())
|
||||||
|
|
||||||
line = line.split()
|
def read(self):
|
||||||
|
readbuffer = "" #Here we store all the messages from server
|
||||||
|
while 1:
|
||||||
|
readbuffer = readbuffer + self.s.recv(1024) #recieve server messages
|
||||||
|
temp = readbuffer.split("\n")
|
||||||
|
readbuffer = temp.pop( )
|
||||||
|
|
||||||
if(line[0] == 'PING'): #If server pings then pong
|
for line in temp:
|
||||||
s.send("PONG %s\r\n" % line[1])
|
line = line.rstrip() #remove trailing 'rn'
|
||||||
|
|
||||||
read()
|
if line.find('PRIVMSG') != -1: #Call a parsing function
|
||||||
|
parsemsg(line, self.channels)
|
||||||
|
|
||||||
|
line = line.split()
|
||||||
|
|
||||||
|
if(line[0] == 'PING'): #If server pings then pong
|
||||||
|
self.s.send("PONG %s\r\n" % line[1])
|
||||||
|
|
||||||
|
def connect(self):
|
||||||
|
self.s = socket.socket( ) #Create the socket
|
||||||
|
self.s.connect((self.host, self.port)) #Connect to server
|
||||||
|
if self.password != None:
|
||||||
|
self.s.send("PASS %s\r\n" % self.password)
|
||||||
|
self.s.send("NICK %s\r\n" % NICK)
|
||||||
|
self.s.send("USER %s %s bla :%s\r\n" % (NICK, self.host, REALNAME))
|
||||||
|
self.read()
|
||||||
|
|
||||||
|
for server in config.getElementsByTagName('server'):
|
||||||
|
srv = Server(server)
|
||||||
|
srv.launch()
|
||||||
|
|
||||||
|
print ("Nemuspeak ready, waiting for new messages...")
|
||||||
|
prompt=""
|
||||||
|
while prompt != "quit":
|
||||||
|
prompt=sys.stdin.readlines ()
|
||||||
|
|
||||||
|
sys.exit(0)
|
||||||
|
27
speak_sample.xml
Normal file
27
speak_sample.xml
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
<config nick="nemubot" realname="nemubot speaker" owner="nemunaire">
|
||||||
|
<!-- Bitlbee/Minbif -->
|
||||||
|
<server server="nemunai.re" port="6666" password="bitlbee" />
|
||||||
|
|
||||||
|
<!-- Rezosup -->
|
||||||
|
<server server="nemunai.re" port="6667">
|
||||||
|
<channel name="#epita" />
|
||||||
|
</server>
|
||||||
|
|
||||||
|
<smiley txt=":)" mood="sourit" />
|
||||||
|
<smiley txt=":(" mood="est triste" />
|
||||||
|
<smiley txt=";)" mood="fait un clin d'oeil" />
|
||||||
|
<smiley txt="<3" mood="aime" />
|
||||||
|
<smiley txt=":'(" mood="pleure" />
|
||||||
|
<smiley txt=";(" mood="pleure" />
|
||||||
|
<smiley txt=":D" mood="rit" />
|
||||||
|
<smiley txt=":d" mood="rit" />
|
||||||
|
<smiley txt="xd" mood="se marre" />
|
||||||
|
<smiley txt="xD" mood="se marre" />
|
||||||
|
<smiley txt="XD" mood="se marre" />
|
||||||
|
<smiley txt="Xd" mood="se marre" />
|
||||||
|
<smiley txt="x)" mood="se marre" />
|
||||||
|
<smiley txt="X)" mood="se marre" />
|
||||||
|
<smiley txt="/o/" mood="danse" />
|
||||||
|
<smiley txt="\\o\\" mood="danse" />
|
||||||
|
<smiley txt="\\o/" mood="fait une accolade" />
|
||||||
|
</config>
|
Loading…
x
Reference in New Issue
Block a user