diff options
author | Jeix <devnull@localhost> | 2011-02-12 10:42:46 +0100 |
---|---|---|
committer | Jeix <devnull@localhost> | 2011-02-12 10:42:46 +0100 |
commit | 2350d53f30de8d45c0f837c8bbdb57b06dece097 (patch) | |
tree | bb6eb6d509f4e9da602689d75f08bc69e510dc3c /module | |
parent | gui optimisations (diff) | |
download | pyload-2350d53f30de8d45c0f837c8bbdb57b06dece097.tar.xz |
xdcc fixes
Diffstat (limited to 'module')
-rw-r--r-- | module/network/XDCCBase.py | 297 | ||||
-rw-r--r-- | module/network/XDCCRequest.py | 16 | ||||
-rw-r--r-- | module/plugins/hoster/Xdcc.py | 14 |
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
|