summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nitzo <nitzo2001@yahoo.com> 2016-08-16 00:10:21 +0200
committerGravatar Nitzo <nitzo2001@yahoo.com> 2016-08-16 00:10:21 +0200
commit30b68ce1ffe595767fb41d973adf701aa2b52a98 (patch)
treedd55b2d31112d0f213f2ff3ad92f497478f1d395
parent[XDCC] Update (diff)
downloadpyload-30b68ce1ffe595767fb41d973adf701aa2b52a98.tar.xz
[XDCC] Update
-rw-r--r--module/plugins/hoster/XDCC.py138
1 files changed, 75 insertions, 63 deletions
diff --git a/module/plugins/hoster/XDCC.py b/module/plugins/hoster/XDCC.py
index 98553ce29..fc1a7e3c3 100644
--- a/module/plugins/hoster/XDCC.py
+++ b/module/plugins/hoster/XDCC.py
@@ -1,30 +1,32 @@
# -*- coding: utf-8 -*-
+import os
import re
import select
import socket
import struct
-import sys
import time
from module.plugins.internal.Hoster import Hoster
-from module.plugins.internal.misc import fsjoin
+from module.plugins.internal.misc import exists, fsjoin
class XDCC(Hoster):
__name__ = "XDCC"
__type__ = "hoster"
- __version__ = "0.41"
+ __version__ = "0.42"
__status__ = "testing"
__pattern__ = r'xdcc://(?P<SERVER>.*?)/#?(?P<CHAN>.*?)/(?P<BOT>.*?)/#?(?P<PACK>\d+)/?'
- __config__ = [("nick", "str", "Nickname", "pyload"),
- ("ident", "str", "Ident", "pyloadident"),
- ("realname", "str", "Realname", "pyloadreal")]
+ __config__ = [("nick", "str", "Nickname", "pyload" ),
+ ("ident", "str", "Ident", "pyloadident" ),
+ ("realname", "str", "Realname", "pyloadreal" ),
+ ("ctcp_version", "str","CTCP version string", "pyLoad! IRC Interface")]
__description__ = """Download from IRC XDCC bot"""
__license__ = "GPLv3"
- __authors__ = [("jeix", "jeix@hasnomail.com")]
+ __authors__ = [("jeix", "jeix@hasnomail.com" ),
+ ("GammaC0de", "nitzo2001[AT]yahoo[DOT]com")]
def setup(self):
@@ -36,45 +38,52 @@ class XDCC(Hoster):
#: Change request type
self.req = self.pyload.requestFactory.getRequest(self.classname, type="XDCC")
- self.pyfile = pyfile
for _i in xrange(0, 3):
try:
nmn = self.do_download(pyfile.url)
- self.log_debug("Download of %s finished." % nmn)
+ self.log_info("Download of %s finished." % nmn)
return
except socket.error, e:
if hasattr(e, "errno") and e.errno is not None:
- errno = e.errno
- else:
- errno = e.args[0]
+ err_no = e.errno
- if errno == 10054:
- self.log_debug("Server blocked our ip, retry in 5 min")
- self.wait(300)
- continue
+ if err_no in (10054, 10061):
+ self.log_warning("Server blocked our ip, retry in 5 min")
+ self.wait(300)
+ continue
- self.log_debug("e: %s" % len(e.args))
- self.fail(_("Failed due to socket errors. Code: %d") % errno)
+ else:
+ self.log_error(_("Failed due to socket errors. Code: %s") % err_no)
+ self.fail(_("Failed due to socket errors. Code: %s") % err_no)
+
+ else:
+ err_msg = e.args[0]
+ self.log_error(_("Failed due to socket errors: '%s'") % err_msg)
+ self.fail(_("Failed due to socket errors: '%s'") % err_msg)
+ self.log_error(_("Server blocked our ip, retry again later manually"))
self.fail(_("Server blocked our ip, retry again later manually"))
def do_download(self, url):
- self.pyfile.setStatus("waiting") #: Real link
+ self.pyfile.setStatus("waiting")
server, chan, bot, pack = re.match(self.__pattern__, url).groups()
- nick = self.config.get('nick')
- ident = self.config.get('ident')
- real = self.config.get('realname')
+ nick = self.config.get('nick')
+ ident = self.config.get('ident')
+ realname = self.config.get('realname')
+ ctcp_version = self.config.get('ctcp_version')
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)
@@ -83,28 +92,27 @@ class XDCC(Hoster):
dl_time = time.time()
sock = socket.socket()
+
+ self.log_info(_("Connecting to: %s:%s") % (host, port))
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("USER %s %s bla :%s\r\n" % (ident, host, realname))
+
+ self.log_info(_("Connect success."))
- self.wait(3)
+ self.wait(5) # Wait for logon to complete
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
m = None
- while True:
-
- #: Done is set if we got our real link
- if done:
- break
-
+ while m is None:
if retry:
if time.time() > retry:
retry = None
@@ -115,6 +123,7 @@ class XDCC(Hoster):
if (dl_time + self.timeout) < time.time(): #@TODO: add in config
sock.send("QUIT :byebye\r\n")
sock.close()
+ self.log_error(_("XDCC Bot did not answer"))
self.fail(_("XDCC Bot did not answer"))
fdset = select.select([sock], [], [], 0)
@@ -122,10 +131,10 @@ class XDCC(Hoster):
continue
readbuffer += sock.recv(1024)
- temp = readbuffer.split("\n")
- readbuffer = temp.pop()
+ lines = readbuffer.split("\n")
+ readbuffer = lines.pop()
- for line in temp:
+ for line in lines:
# if self.pyload.debug:
# self.log_debug("*> " + decode(line))
line = line.rstrip()
@@ -141,20 +150,18 @@ class XDCC(Hoster):
if len(msg) != 4:
continue
- msg = {
- 'origin': msg[0][1:],
- 'action': msg[1],
- 'target': msg[2],
- 'text': msg[3][1:]
- }
+ 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['target'][0:len(nick)] == nick and msg['action'] == "PRIVMSG":
if msg['text'] == "\x01VERSION\x01":
- self.log_debug("Sending CTCP VERSION")
- sock.send("NOTICE %s :%s\r\n" % (msg['origin'], "pyLoad! IRC Interface"))
+ self.log_debug(_("Sending CTCP VERSION"))
+ sock.send("NOTICE %s :%s\r\n" % (msg['origin'], ctcp_version))
elif msg['text'] == "\x01TIME\x01":
- self.log_debug("Sending CTCP TIME")
+ self.log_debug(_("Sending CTCP TIME"))
sock.send("NOTICE %s :%d\r\n" % (msg['origin'], time.time()))
elif msg['text'] == "\x01LAG\x01":
@@ -165,43 +172,48 @@ class XDCC(Hoster):
or msg['action'] not in ("PRIVMSG", "NOTICE"):
continue
- if self.pyload.debug:
- self.log_debug(msg['origin'], msg['text'])
+ self.log_debug(_("PrivMsg: <%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']:
+ elif "you must be on a known channel to request a pack" in msg['text']:
+ self.log_error(_("Invalid channel"))
self.fail(_("Invalid channel"))
- m = re.match('\x01DCC SEND (.*?) (\d+) (\d+)(?: (\d+))?\x01', msg['text'])
- if m is not None:
- done = True
+ m = re.match('\x01DCC SEND (?P<NAME>.*?) (?P<IP>\d+) (?P<PORT>\d+)(?: (?P<SIZE>\d+))?\x01', msg['text'])
#: 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)
+ ip = socket.inet_ntoa(struct.pack('!I', int(m.group('IP'))))
+ port = int(m.group('PORT'))
+ file_name = m.group('NAME')
+ if m.group('SIZE'):
+ self.req.filesize = long(m.group('SIZE'))
+
+ self.pyfile.name = file_name
- if len(m.groups()) > 3:
- self.req.filesize = int(m.group(4))
+ dl_folder = fsjoin(self.pyload.config.get('general', 'download_folder'),
+ self.pyfile.package().folder if self.pyload.config.get("general",
+ "folder_per_package") else "")
+ dl_file = fsjoin(dl_folder, file_name)
- self.pyfile.name = packname
+ if not exists(dl_folder):
+ os.makedirs(dl_folder)
- dl_folder = self.pyload.config.get('general', 'download_folder')
- filename = fsjoin(dl_folder, packname)
+ self.set_permissions(dl_folder)
- self.log_info(_("Downloading %s from %s:%d") % (packname, ip, port))
+ self.log_info(_("Downloading %s from %s:%d") % (file_name, ip, port))
self.pyfile.setStatus("downloading")
- newname = self.req.download(ip, port, filename, sock, self.pyfile.setProgress)
- if newname and newname != filename:
+
+ newname = self.req.download(ip, port, dl_file, sock, self.pyfile.setProgress)
+ if newname and newname != dl_file:
self.log_info(_("%(name)s saved as %(newname)s") % {'name': self.pyfile.name, 'newname': newname})
- filename = newname
+ dl_file = newname
#: kill IRC socket
#: sock.send("QUIT :byebye\r\n")
sock.close()
- self.last_download = filename
+ self.last_download = dl_file
return self.last_download