summaryrefslogtreecommitdiffstats
path: root/module/plugins/hoster/Xdcc.py
diff options
context:
space:
mode:
authorGravatar Jeix <devnull@localhost> 2010-10-24 19:15:12 +0200
committerGravatar Jeix <devnull@localhost> 2010-10-24 19:15:12 +0200
commitec7f2208c99dab2c06f59e764be3bd1c2a2b6b97 (patch)
tree430cdc245c3546186d957d316968e67d96fa7f26 /module/plugins/hoster/Xdcc.py
parentclosed #162 (diff)
downloadpyload-ec7f2208c99dab2c06f59e764be3bd1c2a2b6b97.tar.xz
closed #170
Diffstat (limited to 'module/plugins/hoster/Xdcc.py')
-rw-r--r--module/plugins/hoster/Xdcc.py130
1 files changed, 127 insertions, 3 deletions
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