DCC class can now send files

This commit is contained in:
Némunaire 2012-07-23 04:09:48 +02:00
parent 9a6c1fbb7c
commit 336cab6b2a
2 changed files with 56 additions and 46 deletions

97
DCC.py
View File

@ -1,4 +1,5 @@
import imp import imp
import os
import re import re
import socket import socket
import sys import sys
@ -49,7 +50,7 @@ class DCC(threading.Thread):
@property @property
def id(self): def id(self):
return self.srv.id + "/" + self.named return self.srv.id + "/" + self.sender
def setError(self, msg): def setError(self, msg):
self.error = True self.error = True
@ -93,7 +94,7 @@ class DCC(threading.Thread):
return True return True
def request_user(self, type="CHAT", filename="CHAT"): def request_user(self, type="CHAT", filename="CHAT", size=""):
#Open the port #Open the port
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
try: try:
@ -105,10 +106,10 @@ class DCC(threading.Thread):
except: except:
self.setError("Une erreur s'est produite durant la tentative d'ouverture d'une session DCC.") self.setError("Une erreur s'est produite durant la tentative d'ouverture d'une session DCC.")
return return
print ('Listen on', self.port, "for", self.named) print ('Listen on', self.port, "for", self.sender)
#Send CTCP request for DCC #Send CTCP request for DCC
self.srv.send_ctcp(self.nick, "DCC %s %s %d %d" % (type, filename, self.srv.ip, self.port), "PRIVMSG") self.srv.send_ctcp(self.nick, "DCC %s %s %d %d %s" % (type, filename, self.srv.ip, self.port, size), "PRIVMSG")
s.listen(1) s.listen(1)
#Waiting for the client #Waiting for the client
@ -132,58 +133,64 @@ class DCC(threading.Thread):
self.srv.send_dcc(msg, to) self.srv.send_dcc(msg, to)
def send_file(self, filename): def send_file(self, filename):
self.request_user("FILE", os.path.basename(filename)) if os.path.isfile(filename):
if self.connected: self.messages = filename
with open(filename, 'r') as f: if not self.DCC:
#TODO: don't send the entire file in one packet self.start()
self.conn.sendall(f.read()) self.DCC = True
else:
#TODO: Waiting for response print("File not found `%s'" % filename)
self.conn.close()
self.connected = False
def run(self): def run(self):
self.stopping.clear() self.stopping.clear()
if not self.connected: if not isinstance(self.messages, list):
self.request_user("SEND", os.path.basename(self.messages), os.path.getsize(self.messages))
if self.connected:
with open(self.messages, 'rb') as f:
d = f.read(268435456) #Packets size: 256Mo
while d:
self.conn.sendall(d)
self.conn.recv(4) #The client send a confirmation after each packet
d = f.read(268435456) #Packets size: 256Mo
else:
self.request_user() self.request_user()
#Start by sending all queued messages #Start by sending all queued messages
for mess in self.messages: for mess in self.messages:
self.send_dcc(mess) self.send_dcc(mess)
time.sleep(1) time.sleep(1)
readbuffer = b'' readbuffer = b''
nicksize = len(self.srv.nick) nicksize = len(self.srv.nick)
Bnick = self.srv.nick.encode() Bnick = self.srv.nick.encode()
while not self.stop: while not self.stop:
raw = self.conn.recv(1024) #recieve server messages raw = self.conn.recv(1024) #recieve server messages
if not raw: if not raw:
break break
readbuffer = readbuffer + raw readbuffer = readbuffer + raw
temp = readbuffer.split(b'\n') temp = readbuffer.split(b'\n')
readbuffer = temp.pop() readbuffer = temp.pop()
for line in temp: for line in temp:
if line[:nicksize] == Bnick and line[nicksize+1:].strip()[:10] == b'my name is': if line[:nicksize] == Bnick and line[nicksize+1:].strip()[:10] == b'my name is':
name = line[nicksize+1:].strip()[11:].decode('utf-8', 'replace') name = line[nicksize+1:].strip()[11:].decode('utf-8', 'replace')
if re.match("^[a-zA-Z0-9_-]+$", name): if re.match("^[a-zA-Z0-9_-]+$", name):
if name not in self.srv.dcc_clients: if name not in self.srv.dcc_clients:
del self.srv.dcc_clients[self.sender] del self.srv.dcc_clients[self.sender]
self.nick = name self.nick = name
if len(self.sender.split("!")) > 1: if len(self.sender.split("!")) > 1:
self.sender = self.nick + "!" + self.sender.split("!")[1] self.sender = self.nick + "!" + self.sender.split("!")[1]
else:
self.sender = self.nick
self.srv.dcc_clients[self.sender] = self
self.send_dcc("Hi "+self.nick)
else: else:
self.sender = self.nick self.send_dcc("This nickname is already in use, please choose another one.")
self.srv.dcc_clients[self.sender] = self
self.send_dcc("Hi "+self.nick)
else: else:
self.send_dcc("This nickname is already in use, please choose another one.") self.send_dcc("The name you entered contain invalid char.")
else: else:
self.send_dcc("The name you entered contain invalid char.") self.srv.treat_msg((":%s PRIVMSG %s :" % (self.sender, self.srv.nick)).encode() + line, self.srv, True)
else:
self.srv.treat_msg((":%s PRIVMSG %s :" % (self.sender, self.srv.nick)).encode() + line, self.srv, True)
if self.connected: if self.connected:
self.conn.close() self.conn.close()

View File

@ -284,6 +284,10 @@ class Message:
elif self.cmd[0] == "pvdcctest": elif self.cmd[0] == "pvdcctest":
print("dcctest") print("dcctest")
self.send_snd("Test DCC") self.send_snd("Test DCC")
elif self.cmd[0] == "dccsendtest":
print("dccsendtest")
conn = dcc.DCC(self.srv, self.sender)
conn.send_file("bot_sample.xml")
else: else:
for im in mods: for im in mods:
if im.has_access(self) and im.parseanswer(self): if im.has_access(self) and im.parseanswer(self):
@ -295,7 +299,6 @@ class Message:
return return
#Assume the message starts with nemubot: #Assume the message starts with nemubot:
if self.private: if self.private:
print ("private")
for im in mods: for im in mods:
if im.has_access(self) and im.parseask(self): if im.has_access(self) and im.parseask(self):
return return