diff options
Diffstat (limited to 'module/plugins/hooks/ClickAndLoad.py')
-rw-r--r-- | module/plugins/hooks/ClickAndLoad.py | 166 |
1 files changed, 97 insertions, 69 deletions
diff --git a/module/plugins/hooks/ClickAndLoad.py b/module/plugins/hooks/ClickAndLoad.py index 3c47d30ce..94a240d4c 100644 --- a/module/plugins/hooks/ClickAndLoad.py +++ b/module/plugins/hooks/ClickAndLoad.py @@ -1,91 +1,119 @@ # -*- 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. +import socket - 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. +from threading import Thread, Lock +from time import sleep - You should have received a copy of the GNU General Public License - along with this program; if not, see <http://www.gnu.org/licenses/>. -""" +from module.plugins.Hook import Hook, threaded + + +def forward(source, destination): + string = ' ' + while string: + string = source.recv(1024) + if string: + destination.sendall(string) + else: + destination.shutdown(socket.SHUT_WR) -import socket -import thread -from module.plugins.Hook import Hook +#: socket.create_connection wrapper for python 2.5 +def create_connection(address, timeout=object(), source_address=None): + try: + return socket.create_connection(address, + socket._GLOBAL_DEFAULT_TIMEOUT if type(timeout) == object else timeout, + source_address) + + except SyntaxError: + """Connect to *address* and return the socket object. + + Convenience function. Connect to *address* (a 2-tuple ``(host, + port)``) and return the socket object. Passing the optional + *timeout* parameter will set the timeout on the socket instance + before attempting to connect. If no *timeout* is supplied, the + global default timeout setting returned by :func:`getdefaulttimeout` + is used. If *source_address* is set it must be a tuple of (host, port) + for the socket to bind as a source address before making the connection. + An host of \'\' or port 0 tells the OS to use the default. + """ + + host, port = address + err = None + for res in getaddrinfo(host, port, 0, SOCK_STREAM): + af, socktype, proto, canonname, sa = res + sock = None + try: + sock = socket(af, socktype, proto) + if type(timeout) != object: + sock.settimeout(timeout) + if source_address: + sock.bind(source_address) + sock.connect(sa) + return sock + + except socket.error, _: + err = _ + if sock is not None: + sock.close() + + if err is not None: + raise err + else: + raise socket.error("getaddrinfo returns an empty list") class ClickAndLoad(Hook): - __name__ = "ClickAndLoad" - __version__ = "0.22" - __type__ = "hook" + __name__ = "ClickAndLoad" + __type__ = "hook" + __version__ = "0.31" - __config__ = [("activated", "bool", "Activated", True), - ("extern", "bool", "Allow external link adding", False)] + __config__ = [("activated", "bool", "Activated" , True ), + ("port" , "int" , "Port" , 9666 ), + ("extern" , "bool", "Listen for requests coming from WAN (internet)", False)] - __description__ = """Gives abillity to use jd's click and load. depends on webinterface""" - __author_name__ = ("RaNaN", "mkaay") - __author_mail__ = ("RaNaN@pyload.de", "mkaay@mkaay.de") + __description__ = """Click'N'Load hook plugin""" + __license__ = "GPLv3" + __authors__ = [("RaNaN", "RaNaN@pyload.de"), + ("Walter Purcaro", "vuolter@gmail.com")] def coreReady(self): - self.port = int(self.config['webinterface']['port']) - if self.config['webinterface']['activated']: - try: - if self.getConfig("extern"): - ip = "0.0.0.0" - else: - ip = "127.0.0.1" + if not self.config['webinterface']['activated']: + return - thread.start_new_thread(proxy, (self, ip, self.port, 9666)) - except: - self.logError("ClickAndLoad port already in use.") + ip = "0.0.0.0" if self.getConfig("extern") else "127.0.0.1" + webport = int(self.config['webinterface']['port']) + cnlport = self.getConfig('port') + self.proxy(ip, webport, cnlport) -def proxy(self, *settings): - thread.start_new_thread(server, (self,) + settings) - lock = thread.allocate_lock() - lock.acquire() - lock.acquire() + @threaded + def proxy(self, ip, webport, cnlport): + self.manager.startThread(self.server, ip, webport, cnlport) + lock = Lock() + lock.acquire() + lock.acquire() -def server(self, *settings): - try: - dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - dock_socket.bind((settings[0], settings[2])) - dock_socket.listen(5) - while True: - client_socket = dock_socket.accept()[0] - server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - server_socket.connect(("127.0.0.1", settings[1])) - thread.start_new_thread(forward, (client_socket, server_socket)) - thread.start_new_thread(forward, (server_socket, client_socket)) - except socket.error, e: - if hasattr(e, "errno"): - errno = e.errno - else: - errno = e.args[0] - if errno == 98: - self.logWarning(_("Click'N'Load: Port 9666 already in use")) - return - thread.start_new_thread(server, (self,) + settings) - except: - thread.start_new_thread(server, (self,) + settings) + def server(self, ip, webport, cnlport): + try: + dock_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + dock_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) + dock_socket.bind((ip, cnlport)) + dock_socket.listen(5) -def forward(source, destination): - string = ' ' - while string: - string = source.recv(1024) - if string: - destination.sendall(string) - else: - #source.shutdown(socket.SHUT_RD) - destination.shutdown(socket.SHUT_WR) + while True: + server_socket = dock_socket.accept()[0] + client_socket = create_connection(("127.0.0.1", webport)) + + self.manager.startThread(forward, server_socket, client_socket) + self.manager.startThread(forward, client_socket, server_socket) + + except socket.error, e: + self.logError(e) + + finally: + dock_socket.close() |