amélioré sexiictl et ajouté des commandes
This commit is contained in:
parent
2053ef7388
commit
fd5019f739
|
@ -3,6 +3,7 @@
|
||||||
import socket
|
import socket
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
import struct
|
||||||
|
|
||||||
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
sockpath = "/var/tmp/%s/sexiibot.sock" % os.environ["USER"]
|
sockpath = "/var/tmp/%s/sexiibot.sock" % os.environ["USER"]
|
||||||
|
@ -30,6 +31,30 @@ To get a list of possible commands, use command "help"
|
||||||
|
|
||||||
args = sys.argv
|
args = sys.argv
|
||||||
|
|
||||||
|
def send_msg(connexion, msg):
|
||||||
|
# Prefix each message with a 4-byte length (network byte order)
|
||||||
|
msg = struct.pack('>I', len(msg)) + msg
|
||||||
|
connexion.sendall(msg)
|
||||||
|
|
||||||
|
def recv_msg(connection):
|
||||||
|
# Read message length and unpack it into an integer
|
||||||
|
raw_msglen = recvall(connection, 4)
|
||||||
|
if not raw_msglen:
|
||||||
|
return b''
|
||||||
|
msglen = struct.unpack('>I', raw_msglen)[0]
|
||||||
|
# Read the message data
|
||||||
|
return recvall(connection, msglen)
|
||||||
|
|
||||||
|
def recvall(connection,n):
|
||||||
|
# Helper function to recv n bytes or return None if EOF is hit
|
||||||
|
data = b''
|
||||||
|
while len(data) < n:
|
||||||
|
packet = connection.recv(n - len(data))
|
||||||
|
if not packet:
|
||||||
|
return b''
|
||||||
|
data += packet
|
||||||
|
return data
|
||||||
|
|
||||||
if len(args) < 2:
|
if len(args) < 2:
|
||||||
print(usage, file=sys.stderr)
|
print(usage, file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
@ -47,7 +72,6 @@ else:
|
||||||
message = " ".join(args[1:])
|
message = " ".join(args[1:])
|
||||||
|
|
||||||
try:
|
try:
|
||||||
print(message)
|
|
||||||
sock.connect(sockpath)
|
sock.connect(sockpath)
|
||||||
except socket.error:
|
except socket.error:
|
||||||
error = """\
|
error = """\
|
||||||
|
@ -64,6 +88,8 @@ If you need help to generate a config file, use the sexiiwizard script.
|
||||||
print(error, file=sys.stderr)
|
print(error, file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
try:
|
try:
|
||||||
sock.sendall(bytes(message, 'UTF-8'))
|
send_msg(sock, bytes(message, 'UTF-8'))
|
||||||
|
response = recv_msg(sock).decode('UTF-8')
|
||||||
|
print(response)
|
||||||
finally:
|
finally:
|
||||||
sock.close()
|
sock.close()
|
||||||
|
|
|
@ -51,6 +51,8 @@ class Channel(object):
|
||||||
return self.__name
|
return self.__name
|
||||||
|
|
||||||
def message(self, msg):
|
def message(self, msg):
|
||||||
|
while self.__in == None:
|
||||||
|
time.sleep(0.1)
|
||||||
print("%s <-- %s" % (self.__name, msg))
|
print("%s <-- %s" % (self.__name, msg))
|
||||||
self.__in.write("%s\n" % msg)
|
self.__in.write("%s\n" % msg)
|
||||||
|
|
||||||
|
|
102
sexiibot/core.py
102
sexiibot/core.py
|
@ -18,11 +18,12 @@ import time
|
||||||
import threading
|
import threading
|
||||||
import shutil
|
import shutil
|
||||||
import socket
|
import socket
|
||||||
|
import struct
|
||||||
|
|
||||||
class Sexiibot(object):
|
class Sexiibot(object):
|
||||||
"""Core sexiibot class"""
|
"""Core sexiibot class"""
|
||||||
|
|
||||||
def __init__(self, server, nick, new=True, port=None, ssl=False, channels=[], realname=None, iipath=None, sock="./sexiibot.sock"):
|
def __init__(self, server, nick, new=True, port=None, ssl=False, channels=[], realname=None, iipath=None, sock="/var/tmp/%s/sexiibot.sock" % os.environ["USER"]):
|
||||||
if new:
|
if new:
|
||||||
self.__server = server
|
self.__server = server
|
||||||
else:
|
else:
|
||||||
|
@ -44,6 +45,9 @@ class Sexiibot(object):
|
||||||
self.__treated = channels
|
self.__treated = channels
|
||||||
self.__quit = False
|
self.__quit = False
|
||||||
self.__watch = None
|
self.__watch = None
|
||||||
|
sockdir = os.path.dirname(sock)
|
||||||
|
if not os.path.exists(sockdir):
|
||||||
|
os.makedirs(sockdir)
|
||||||
self.__sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
self.__sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
try:
|
try:
|
||||||
os.unlink(sock)
|
os.unlink(sock)
|
||||||
|
@ -108,19 +112,37 @@ class Sexiibot(object):
|
||||||
self.__nick = nick
|
self.__nick = nick
|
||||||
|
|
||||||
def newChan(self, args):
|
def newChan(self, args):
|
||||||
if len(args) == 1:
|
if len(args) > 0:
|
||||||
|
if args[0] in self.__channels:
|
||||||
|
return "warning: already joined %s" % args[0]
|
||||||
chan = Channel(args[0],self)
|
chan = Channel(args[0],self)
|
||||||
self.__channels[args[0]] = chan
|
self.__channels[args[0]] = chan
|
||||||
chan.join()
|
chan.join()
|
||||||
|
response = ""
|
||||||
|
if len(args) > 1:
|
||||||
|
response += "warning: \"" + ' '.join(args[1:]) + "\" garbage\n"
|
||||||
|
response += "Successfully joined %s" % args[0]
|
||||||
|
return response
|
||||||
|
else:
|
||||||
|
return "usage: join <channel>"
|
||||||
|
|
||||||
def leaveChan(self, args):
|
def leaveChan(self, args):
|
||||||
if len(args) == 1:
|
|
||||||
self.__channels[args[0]].leave()
|
if len(args) > 0:
|
||||||
elif if len(args) == 2:
|
if args[0] not in self.__channels:
|
||||||
self.__channels[args[0]].leave(args[1])
|
return "warning: not in %s" % args[0]
|
||||||
|
response = ""
|
||||||
|
if len(args) == 1:
|
||||||
|
self.__channels[args[0]].leave()
|
||||||
|
else:
|
||||||
|
self.__channels[args[0]].leave(args[1])
|
||||||
|
if not args[1:] == []:
|
||||||
|
response += "warning: \"%s\" garbage\n" % " ".join(args[1:])
|
||||||
|
del self.__channels[args[0]]
|
||||||
|
response += "Successfully leaved %s" % args[0]
|
||||||
|
return response
|
||||||
else:
|
else:
|
||||||
return "warning: \"%s\" garbage"
|
return "usage: leave <channel> [message]"
|
||||||
del self.__channels[args[0]]
|
|
||||||
|
|
||||||
def incomingChan(self, dirname):
|
def incomingChan(self, dirname):
|
||||||
root = self.getIrcPath()
|
root = self.getIrcPath()
|
||||||
|
@ -129,7 +151,6 @@ class Sexiibot(object):
|
||||||
chan = Channel(dirname, self, connected=True)
|
chan = Channel(dirname, self, connected=True)
|
||||||
chan.join()
|
chan.join()
|
||||||
self.__channels[dirname] = chan
|
self.__channels[dirname] = chan
|
||||||
|
|
||||||
|
|
||||||
def watchChan(self):
|
def watchChan(self):
|
||||||
root = self.getIrcPath()
|
root = self.getIrcPath()
|
||||||
|
@ -143,34 +164,63 @@ class Sexiibot(object):
|
||||||
self.__treated += [chan]
|
self.__treated += [chan]
|
||||||
time.sleep(0.1)
|
time.sleep(0.1)
|
||||||
|
|
||||||
|
def send_msg(self, connection, msg):
|
||||||
|
# Prefix each message with a 4-byte length (network byte order)
|
||||||
|
msg = struct.pack('>I', len(msg)) + msg
|
||||||
|
connection.sendall(msg)
|
||||||
|
|
||||||
|
def recv_msg(self, connection):
|
||||||
|
# Read message length and unpack it into an integer
|
||||||
|
raw_msglen = self.recvall(connection, 4)
|
||||||
|
if not raw_msglen:
|
||||||
|
return b''
|
||||||
|
msglen = struct.unpack('>I', raw_msglen)[0]
|
||||||
|
# Read the message data
|
||||||
|
return self.recvall(connection, msglen)
|
||||||
|
|
||||||
|
def recvall(self, connection,n):
|
||||||
|
# Helper function to recv n bytes or return None if EOF is hit
|
||||||
|
data = b''
|
||||||
|
while len(data) < n:
|
||||||
|
packet = connection.recv(n - len(data))
|
||||||
|
if not packet:
|
||||||
|
return b''
|
||||||
|
data += packet
|
||||||
|
return data
|
||||||
|
|
||||||
def listenCommands(self):
|
def listenCommands(self):
|
||||||
self.__sock.listen(1)
|
self.__sock.listen(1)
|
||||||
while not self.__quit:
|
while not self.__quit:
|
||||||
connection, client = self.__sock.accept()
|
connection, client = self.__sock.accept()
|
||||||
try:
|
try:
|
||||||
command = ""
|
command = self.recv_msg(connection).decode('UTF-8')
|
||||||
while True:
|
print("*** command from control socket: %s" % command)
|
||||||
data = connection.recv(16)
|
self.parseCommand(command, connection)
|
||||||
command += data.decode('UTF-8')
|
|
||||||
if not data:
|
|
||||||
self.parseCommand(command, connexion)
|
|
||||||
break
|
|
||||||
finally:
|
finally:
|
||||||
connection.close()
|
connection.close()
|
||||||
|
|
||||||
def parseCommand(self, command, connexion):
|
def parseCommand(self, command, connection):
|
||||||
cmd = command.split(" ")
|
cmd = command.split(" ")
|
||||||
order = {
|
orders = {
|
||||||
"join" : self.newChan,
|
"join" : { "method": self.newChan, "desc": "join a new channel" },
|
||||||
"leave" : self.leaveChan,
|
"leave" : { "method": self.leaveChan, "desc": "leave an existing channel" },
|
||||||
"quit" : self.quit,
|
"quit" : { "method": self.quit, "desc": "quit sexiibot instance" },
|
||||||
"say" : self.messageChan,
|
"say" : { "method": self.messageChan, "desc": "say a message on a channel" },
|
||||||
"action" : self.actionChan,
|
"action" : { "method": self.actionChan, "desc": "send an action message on a channel" },
|
||||||
"nick" : self.setNick
|
"nick" : { "method": self.setNick, "desc": "get or change nick" },
|
||||||
}
|
}
|
||||||
#connection.sendall(order[cmd[0]](cmd[1:], 'UTF-8'))
|
if cmd[0] == "help":
|
||||||
|
message = "Welcome to sexiibot control help. Here is the list of available commands:\n"
|
||||||
|
for item in orders:
|
||||||
|
message += " %s: %s\n" % (item, orders[item]["desc"])
|
||||||
|
message += " help: displays this help\n\n"
|
||||||
|
message += "To have specific help for a command, just use it without any argument.\n"
|
||||||
|
message += "Sexiibot loves you."
|
||||||
|
self.send_msg(connection, bytes(message, 'UTF-8'))
|
||||||
|
else:
|
||||||
|
self.send_msg(connection, bytes(orders[cmd[0]]["method"](cmd[1:]), 'UTF-8'))
|
||||||
|
|
||||||
def quit(selfi, args=[]):
|
def quit(self, args=[]):
|
||||||
for chan in self.__channels:
|
for chan in self.__channels:
|
||||||
self.leaveChan([chan, "sexiibot stopping"])
|
self.leaveChan([chan, "sexiibot stopping"])
|
||||||
self.__quit = True
|
self.__quit = True
|
||||||
|
|
Loading…
Reference in New Issue