summaryrefslogtreecommitdiffstats
path: root/module
diff options
context:
space:
mode:
authorGravatar Jeix <devnull@localhost> 2011-02-12 10:42:46 +0100
committerGravatar Jeix <devnull@localhost> 2011-02-12 10:42:46 +0100
commit2350d53f30de8d45c0f837c8bbdb57b06dece097 (patch)
treebb6eb6d509f4e9da602689d75f08bc69e510dc3c /module
parentgui optimisations (diff)
downloadpyload-2350d53f30de8d45c0f837c8bbdb57b06dece097.tar.xz
xdcc fixes
Diffstat (limited to 'module')
-rw-r--r--module/network/XDCCBase.py297
-rw-r--r--module/network/XDCCRequest.py16
-rw-r--r--module/plugins/hoster/Xdcc.py14
3 files changed, 19 insertions, 308 deletions
diff --git a/module/network/XDCCBase.py b/module/network/XDCCBase.py
deleted file mode 100644
index 1b9da1a23..000000000
--- a/module/network/XDCCBase.py
+++ /dev/null
@@ -1,297 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 3 of the License,
- or (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- See the GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, see <http://www.gnu.org/licenses/>.
-
- @author: mkaay
-"""
-
-import socket
-import socks
-import re
-
-from os.path import getsize
-from urlparse import urlparse
-from urllib2 import _parse_proxy
-
-from helper import *
-from time import sleep
-
-import struct
-from select import select
-
-class XDCCError(Exception):
- pass
-
-class WrappedXDCCDeferred(WrappedDeferred):
- pass
-
-class XDCCDownload():
- def __init__(self, server, port, channel, bot, pack, nick, ident, real, filename, timeout=30, bucket=None, interface=None, proxies={}):
- self.server = server
- self.port = port
- self.channel = channel
- self.bot = bot
- self.pack = pack
- self.nick = nick
- self.ident = ident
- self.real = real
- self.filename = filename
- self.bucket = bucket
- self.interface = interface
- self.proxies = proxies
- self.timeout = timeout
- self.debug = 2
-
- self.deferred = Deferred()
-
- self.finished = False
- self.size = None
-
- self.speed = 0
-
- self.abort = False
-
- self.arrived = 0
-
- self.startTime = None
- self.endTime = None
-
- self.speed = 0 #byte/sec
- self.speedCalcTime = None
- self.speedCalcLen = 0
-
- self.fh = None
-
- def createSocket(self):
- proxytype = None
- proxy = None
- if self.proxies.has_key("socks5"):
- proxytype = socks.PROXY_TYPE_SOCKS5
- proxy = self.proxies["socks5"]
- elif self.proxies.has_key("socks4"):
- proxytype = socks.PROXY_TYPE_SOCKS4
- proxy = self.proxies["socks4"]
- if proxytype:
- sock = socks.socksocket()
- t = _parse_proxy(proxy)
- sock.setproxy(proxytype, addr=t[3].split(":")[0], port=int(t[3].split(":")[1]), username=t[1], password=t[2])
- else:
- sock = socket.socket()
- return sock
-
- def _download(self, ip, port):
- startTime = inttime()
-
- dccsock = self.createSocket()
-
- dccsock.settimeout(self.timeout)
- dccsock.bind(self.sourceAddress)
- dccsock.connect((ip, port))
-
- # recv loop for dcc socket
- while True:
- if self.abort:
- break
- count = 4096
- if self.bucket:
- count = self.bucket.add(count)
- if count < 4096:
- sleep(0.01)
- continue
-
- try:
- data = dccsock.recv(count)
- except:
- self.deferred.error("timeout")
-
- if self.speedCalcTime < inttime():
- self.speed = self.speedCalcLen
- self.speedCalcTime = inttime()
- self.speedCalcLen = 0
- try:
- self.deferred.progress("percent", 100-int((self.size - self.arrived)/float(self.size)*100))
- except:
- pass
- size = len(data)
- self.speedCalcLen += size
- self.arrived += size
-
- if not data:
- break
-
- self.fh.write(data)
-
- # acknowledge data by sending number of recceived bytes
- dccsock.send(struct.pack('!I', self.arrived))
-
- dccsock.close()
- self.fh.close()
-
- self.endTime = inttime()
- if self.abort:
- self.deferred.error("abort")
- elif self.size is None or self.size == self.arrived:
- self.deferred.callback()
- else:
- self.deferred.error("wrong content lenght")
-
- def download(self):
- self.fh = open(self.filename, "wb")
-
- def debug(s):
- print "XDCC:", s
-
- sock = self.createSocket()
- print self.server, self.port
- sock.connect((self.server, int(self.port)))
- _realsend = sock.send
- def send(s):
- if self.debug == 2:
- print s
- _realsend(s)
- sock.send = send
-
- sock.send("NICK %s\r\n" % self.nick)
- sock.send("USER %s %s bla :%s\r\n" % (self.ident, self.server, self.real))
- sleep(3)
- sock.send("JOIN #%s\r\n" % self.channel)
- sock.send("PRIVMSG %s :xdcc send #%s\r\n" % (self.bot, self.pack))
-
- # IRC recv loop
- readbuffer = ""
- dlTime = inttime()
- done = False
- retry = None
- while True:
- # done is set if we got our real link
- if done: break
-
- if retry:
- if inttime() > retry:
- retry = None
- dlTime = inttime()
- sock.send("PRIVMSG %s :xdcc send #%s\r\n" % (self.bot, self.pack))
-
- else:
- if (dlTime + self.timeout) < inttime():
- sock.send("QUIT :byebye\r\n")
- sock.close()
- raise XDCCError("XDCC Bot did not answer")
-
-
- 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":
- raise XDCCError("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 self.nick == msg["target"][0:len(self.nick)] and "PRIVMSG" == msg["action"]:
- if msg["text"] == "\x01VERSION\x01":
- debug("XDCC: Sending CTCP VERSION.")
- sock.send("NOTICE %s :%s\r\n" % (msg['origin'], "pyLoad! IRC Interface"))
- elif msg["text"] == "\x01TIME\x01":
- debug("Sending CTCP TIME.")
- sock.send("NOTICE %s :%d\r\n" % (msg['origin'], inttime()))
- elif msg["text"] == "\x01LAG\x01":
- pass # don't know how to answer
-
- if not (self.bot == msg["origin"][0:len(self.bot)]
- and self.nick == msg["target"][0:len(self.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 = inttime() + 300
-
- if "you must be on a known channel to request a pack" in msg["text"]:
- raise XDCCError("Wrong channel")
-
- m = re.match('\x01DCC SEND (.*?) (\d+) (\d+)(?: (\d+))?\x01', msg["text"])
- if m is not None:
- done = True
-
- # get connection data
- ip = socket.inet_ntoa(struct.pack('L', socket.ntohl(int(m.group(2)))))
- port = int(m.group(3))
- self.realfilename = m.group(1)
-
- if len(m.groups()) > 3:
- self.size = int(m.group(4))
-
- debug("XDCC: Downloading %s from %s:%d" % (packname, ip, port))
-
- self._download(ip, port)
- return WrappedXDCCDeferred(self, self.deferred)
-
-if __name__ == "__main__":
- import sys
- from Bucket import Bucket
- bucket = Bucket()
- #bucket.setRate(200*1000)
- bucket = None
-
- finished = False
- def err(*a, **b):
- print a, b
- def callb(*a, **b):
- global finished
- finished = True
- print a, b
-
- print "starting"
- dwnld = XDCCDownload("<server>", 6667, "<chan>", "<bot>", "<pack>", "<nick>", "<ident>", "<real>", "<filename>")
- d = dwnld.download()
- d.addCallback(callb)
- d.addErrback(err)
-
- try:
- while True:
- if not dwnld.finished:
- print dwnld.speed/1024, "kb/s", "size", dwnld.arrived, "/", dwnld.size#, int(float(dwnld.arrived)/dwnld.size*100), "%"
- if finished:
- print "- finished"
- break
- sleep(1)
- except KeyboardInterrupt:
- dwnld.abort = True
- sys.exit()
diff --git a/module/network/XDCCRequest.py b/module/network/XDCCRequest.py
index 126662bb8..01015cc62 100644
--- a/module/network/XDCCRequest.py
+++ b/module/network/XDCCRequest.py
@@ -64,7 +64,8 @@ class XDCCRequest():
def download(self, ip, port, filename, progressNotify=None):
- lastRecv = time()
+ lastUpdate = time()
+ cumRecvLen = 0
dccsock = self.createSocket()
@@ -93,13 +94,18 @@ class XDCCRequest():
dataLen = len(data)
self.recv += dataLen
+ cumRecvLen += dataLen
+
now = time()
- timespan = now - lastRecv
- if timespan:
- self.speed = dataLen / timespan
+ timespan = now - lastUpdate
+ if timespan > 1:
+ self.speed = cumRecvLen / timespan
+ cumRecvLen = 0
+ lastUpdate = now
+
if progressNotify:
progressNotify(self.percent)
- lastRecv = now
+
if not data:
break
diff --git a/module/plugins/hoster/Xdcc.py b/module/plugins/hoster/Xdcc.py
index 4ed718823..5dc1aafb8 100644
--- a/module/plugins/hoster/Xdcc.py
+++ b/module/plugins/hoster/Xdcc.py
@@ -45,8 +45,8 @@ class Xdcc(Hoster):
__author_mail__ = ("jeix@hasnomail.com")
def setup(self):
- self.debug = 2 #0,1,2
- self.timeout = 10
+ self.debug = 0 #0,1,2
+ self.timeout = 30
self.multiDL = False
@@ -122,10 +122,13 @@ class Xdcc(Hoster):
readbuffer = ""
done = False
retry = None
+ m = None
while True:
+
# done is set if we got our real link
- if done: break
-
+ if done:
+ break
+
if retry:
if time.time() > retry:
retry = None
@@ -188,7 +191,6 @@ class Xdcc(Hoster):
if self.debug is 1:
print "%s: %s" % (msg["origin"], msg["text"])
- # You already requested that pack
if "You already requested that pack" in msg["text"]:
retry = time.time() + 300
@@ -196,7 +198,7 @@ class Xdcc(Hoster):
self.fail("Wrong channel")
m = re.match('\x01DCC SEND (.*?) (\d+) (\d+)(?: (\d+))?\x01', msg["text"])
- if m != None:
+ if m:
done = True
# get connection data