From ec7f2208c99dab2c06f59e764be3bd1c2a2b6b97 Mon Sep 17 00:00:00 2001 From: Jeix Date: Sun, 24 Oct 2010 19:15:12 +0200 Subject: closed #170 --- module/network/XdccRequest.py | 89 +----------------------- module/plugins/hooks/IRCInterface.py | 2 +- module/plugins/hoster/Xdcc.py | 130 ++++++++++++++++++++++++++++++++++- 3 files changed, 131 insertions(+), 90 deletions(-) (limited to 'module') diff --git a/module/network/XdccRequest.py b/module/network/XdccRequest.py index 98e3e9f12..dec71adf7 100644 --- a/module/network/XdccRequest.py +++ b/module/network/XdccRequest.py @@ -83,9 +83,8 @@ class XdccRequest: # @TODO: pycurl proxy protocoll selection raise NotImplementedError - # xdcc://irc.Abjects.net/[XDCC]|Shit/#0004/ - #nick, ident, realname, servers - def download(self, bot, pack, path, nick, ident, realname, channel, host, port=6667): + + def download(self, ip, port, location, name): self.dl_time = time.time() self.dl = True @@ -120,93 +119,11 @@ class XdccRequest: self.chunkRead += chunkSize self.dl_arrived += chunkSize - - # connect to IRC - sock = socket.socket() - sock.connect((host, port)) - if nick == "pyload": - nick = "pyload-%d" % (time.time() % 1000) # last 3 digits - sock.send("NICK %s\r\n" % nick) - sock.send("USER %s %s bla :%s\r\n" % (ident, host, realname)) - sock.send("JOIN #%s\r\n" % channel) - sock.send("PRIVMSG %s :xdcc send #%s\r\n" % (bot, pack)) - - # IRC recv loop - readbuffer = "" - while True: - if self.abort: - raise AbortDownload - - if self.dl_time + self.timeout < time.time(): - raise XDCCError("timeout, bot did not answer") - - #time.sleep(5) # cool down <- was a bullshit idea - - fdset = select([sock], [], [], 0) - if sock not in fdset[0]: - continue - - readbuffer += sock.recv(1024) - temp = readbuffer.split("\n") - readbuffer = temp.pop() - - for line in temp: - if self.debug: print "*> " + line - line = line.rstrip() - first = line.split() - - if(first[0] == "PING"): - sock.send("PONG %s\r\n" % first[1]) - - if first[0] == "ERROR": - raise IRCError(line) - - msg = line.split(None, 3) - if len(msg) != 4: - continue - - msg = { \ - "origin":msg[0][1:], \ - "action":msg[1], \ - "target":msg[2], \ - "text" :msg[3][1:] \ - } - - - if nick == msg["target"][0:len(nick)]\ - and "PRIVMSG" == msg["action"]: - if msg["text"] == "\x01VERSION\x01": - if self.debug: print "Sending CTCP VERSION." - sock.send("NOTICE %s :%s\r\n" % (msg['origin'], "pyLoad! IRC Interface")) - elif msg["text"] == "\x01TIME\x01": - if self.debug: print "Sending CTCP TIME." - sock.send("NOTICE %s :%d\r\n" % (msg['origin'], time.time())) - elif msg["text"] == "\x01LAG\x01": - pass # don't know how to answer - - if not (bot == msg["origin"][0:len(bot)] - and nick == msg["target"][0:len(nick)] - and "PRIVMSG" == msg["action"]): - continue - - m = re.match('\x01DCC SEND (.*?) (.*?) (.*?) (.*?)\x01', msg["text"]) - if m is not None: - break - - # kill IRC socket - sock.send("QUIT :byebye\r\n") - sock.close() # connect to XDCC Bot dcc = socket.socket() - ip = socket.inet_ntoa(struct.pack('L', socket.ntohl(int(m.group(2))))) - port = int(m.group(3)) dcc.connect((ip, port)) - - dcc_packname = m.group(1) - if len(m.groups()) > 3: - self.dl_size = int(m.group(4)) - dcc_packname = self.get_free_name(path + '\\' + dcc_packname) + dcc_packname = self.get_free_name(location + '\\' + name) dcc_fpointer = open(dcc_packname + ".part", "wb") dcc_total = 0 diff --git a/module/plugins/hooks/IRCInterface.py b/module/plugins/hooks/IRCInterface.py index 404cf407a..dc868ede9 100644 --- a/module/plugins/hooks/IRCInterface.py +++ b/module/plugins/hooks/IRCInterface.py @@ -118,7 +118,7 @@ class IRCInterface(Thread, Hook): first = line.split() if(first[0] == "PING"): - self.sock.send("PING %s\r\n" % first[1]) + self.sock.send("PONG %s\r\n" % first[1]) if first[0] == "ERROR": raise IRCError(line) diff --git a/module/plugins/hoster/Xdcc.py b/module/plugins/hoster/Xdcc.py index 52ece4ca4..d04d65857 100644 --- a/module/plugins/hoster/Xdcc.py +++ b/module/plugins/hoster/Xdcc.py @@ -24,6 +24,9 @@ from os.path import exists from os import makedirs import re import sys +import time +import socket, struct +from select import select from module.plugins.Hoster import Hoster @@ -42,12 +45,17 @@ class Xdcc(Hoster): __author_name__ = ("jeix") __author_mail__ = ("jeix@hasnomail.com") + def setup(self): + self.debug = 0#2 #0,1,2 + self.timeout = 10 + self.multiDL = False + def process(self, pyfile): self.req = pyfile.m.core.requestFactory.getRequest(self.__name__, type="XDCC") self.doDownload(pyfile.url) def doDownload(self, url): - self.pyfile.setStatus("downloading") + self.pyfile.setStatus("waiting") # real link download_folder = self.config['general']['download_folder'] location = join(download_folder, self.pyfile.package().folder.decode(sys.getfilesystemencoding())) @@ -63,9 +71,125 @@ class Xdcc(Hoster): ident = self.getConf('ident') real = self.getConf('realname') - newname = self.req.download(bot, pack, location, nick, ident, real, chan, server) + temp = server.split(':') + ln = len(temp) + if ln == 2: + host, port = temp + elif ln == 1: + host, port = temp[0], 6667 + else: + self.fail("Invalid hostname for IRC Server (%s)" % server) + + + ####################### + # CONNECT TO IRC AND IDLE FOR REAL LINK + dl_time = time.time() + + sock = socket.socket() + sock.connect((host, int(port))) + if nick == "pyload": + nick = "pyload-%d" % (time.time() % 1000) # last 3 digits + sock.send("NICK %s\r\n" % nick) + sock.send("USER %s %s bla :%s\r\n" % (ident, host, real)) + + sock.send("JOIN #%s\r\n" % chan) + sock.send("PRIVMSG %s :xdcc send #%s\r\n" % (bot, pack)) + + # IRC recv loop + readbuffer = "" + done = False + retry = None + while True: + # done is set if we got our real link + if done: break + + if not retry: + if dl_time + self.timeout < time.time(): # todo: add in config + sock.send("QUIT :byebye\r\n") + sock.close() + self.fail("XDCC Bot did not answer") + + if time.time() > retry: + retry = None + dl_time = time.time() + sock.send("PRIVMSG %s :xdcc send #%s\r\n" % (bot, pack)) + + fdset = select([sock], [], [], 0) + if sock not in fdset[0]: + continue + + readbuffer += sock.recv(1024) + temp = readbuffer.split("\n") + readbuffer = temp.pop() + + for line in temp: + if self.debug is 2: print "*> " + line + line = line.rstrip() + first = line.split() + + if(first[0] == "PING"): + sock.send("PONG %s\r\n" % first[1]) + + if first[0] == "ERROR": + self.fail("IRC-Error: %s" % line) + + msg = line.split(None, 3) + if len(msg) != 4: + continue + + msg = { \ + "origin":msg[0][1:], \ + "action":msg[1], \ + "target":msg[2], \ + "text" :msg[3][1:] \ + } + + + if nick == msg["target"][0:len(nick)] and "PRIVMSG" == msg["action"]: + if msg["text"] == "\x01VERSION\x01": + self.log.debug("XDCC: Sending CTCP VERSION.") + sock.send("NOTICE %s :%s\r\n" % (msg['origin'], "pyLoad! IRC Interface")) + elif msg["text"] == "\x01TIME\x01": + self.log.debug("Sending CTCP TIME.") + sock.send("NOTICE %s :%d\r\n" % (msg['origin'], time.time())) + elif msg["text"] == "\x01LAG\x01": + pass # don't know how to answer + + if not (bot == msg["origin"][0:len(bot)] + and nick == msg["target"][0:len(nick)] + and msg["action"] in ("PRIVMSG", "NOTICE")): + continue + + if self.debug is 1: + print "%s: %s" % (msg["origin"], msg["text"]) + + if "You already requested that pack" in msg["text"]: + retry = time.time() + 300 + + if "you must be on a known channel to request a pack" in msg["text"]: + self.fail("Wrong channel") + + m = re.match('\x01DCC SEND (.*?) (\d+) (\d+)(?: (\d+))?\x01', msg["text"]) + if m != None: + done = True + + # get connection data + ip = socket.inet_ntoa(struct.pack('L', socket.ntohl(int(m.group(2))))) + port = int(m.group(3)) + packname = m.group(1) + + if len(m.groups()) > 3: + self.req.dl_size = int(m.group(4)) + + self.log.debug("XDCC: Downloading %s from %s:%d" % (packname, ip, port)) + + self.pyfile.setStatus("downloading") + newname = self.req.download(host, port, location, packname) self.pyfile.size = self.req.dl_size + + # kill IRC socket + sock.send("QUIT :byebye\r\n") + sock.close() if newname: self.pyfile.name = newname - \ No newline at end of file -- cgit v1.2.3