diff options
author | RaNaN <Mast3rRaNaN@hotmail.de> | 2009-06-26 11:37:44 +0200 |
---|---|---|
committer | RaNaN <Mast3rRaNaN@hotmail.de> | 2009-06-26 11:37:44 +0200 |
commit | e260b201f94a2a1e470b85a6499ea70e20a11277 (patch) | |
tree | 356dc9f5a7d8ef14cf6befb8cfa324b991571a0c | |
parent | fixed occasionally appearing cli bug, catpcha method for sharebiz @ ~60% (diff) | |
download | pyload-e260b201f94a2a1e470b85a6499ea70e20a11277.tar.xz |
Cli stable, able to abort downloads, pause/kill server
-rw-r--r-- | Plugins/RapidshareCom.py | 1 | ||||
-rw-r--r-- | module/download_thread.py | 5 | ||||
-rw-r--r-- | module/file_list.py | 14 | ||||
-rwxr-xr-x | module/network/Request.py | 6 | ||||
-rw-r--r-- | module/thread_list.py | 9 | ||||
-rw-r--r-- | pyLoadCli.py | 100 | ||||
-rw-r--r-- | pyLoadCore.py | 18 |
7 files changed, 116 insertions, 37 deletions
diff --git a/Plugins/RapidshareCom.py b/Plugins/RapidshareCom.py index 4eb7bf93d..b34576d23 100644 --- a/Plugins/RapidshareCom.py +++ b/Plugins/RapidshareCom.py @@ -130,6 +130,7 @@ class RapidshareCom(Plugin): file_url_pattern = r".*name=\"dlf\" action=\"(.*)\" method=.*" return re.search(file_url_pattern, self.html[1]).group(1) else: + print self.html[1] #test print raise Exception, "Error when retrieving download url" def get_file_name(self): diff --git a/module/download_thread.py b/module/download_thread.py index 202ebcafb..2c9cc8791 100644 --- a/module/download_thread.py +++ b/module/download_thread.py @@ -22,6 +22,7 @@ import traceback from time import sleep from time import time +from module.network.Request import AbortDownload class Status(object): """ Saves all status information @@ -53,7 +54,6 @@ class Status(object): class Reconnect(Exception): pass - class Download_Thread(threading.Thread): def __init__(self, parent): threading.Thread.__init__(self) @@ -70,6 +70,9 @@ class Download_Thread(threading.Thread): if self.loadedPyFile: try: self.download(self.loadedPyFile) + except AbortDownload: + self.loadedPyFile.plugin.req.abort = False + self.loadedPyFile.status.type = "aborted" except Reconnect: pass except Exception, e: diff --git a/module/file_list.py b/module/file_list.py index 8f32ef474..feb7613bd 100644 --- a/module/file_list.py +++ b/module/file_list.py @@ -20,6 +20,8 @@ LIST_VERSION = 2 +from threading import RLock + import cPickle from Py_Load_File import PyLoadFile from module.remote.RequestObject import RequestObject @@ -29,6 +31,7 @@ class File_List(object): self.core = core self.files = [] self.data = {'version': LIST_VERSION, 'order': []} + self.lock = RLock() self.load() def new_pyfile(self, url): @@ -61,6 +64,7 @@ class File_List(object): del self.data[pyfile.id] def remove_id(self, pyid): + #also abort download pyid = int(pyid) found = False for pyfile in self.files: @@ -70,6 +74,10 @@ class File_List(object): break if not found: + for pyfile in self.core.thread_list.py_downloading: + if pyfile.id == pyid: + pyfile.plugin.req.abort = True + break return False self.data['order'].remove(pyid) @@ -84,10 +92,14 @@ class File_List(object): return id def save(self): + self.lock.acquire() + output = open('links.pkl', 'wb') cPickle.dump(self.data, output, -1) self.inform_client() + + self.lock.release() def load(self): try: @@ -102,7 +114,7 @@ class File_List(object): for i in obj['order']: self.append(obj[i].url) - self.core.logger.info("Links loaded: "+ str(int(len(obj) - 1))) + self.core.logger.info("Links loaded: " + str(int(len(obj) - 1))) def inform_client(self): obj = RequestObject() diff --git a/module/network/Request.py b/module/network/Request.py index 0b518cf66..346412446 100755 --- a/module/network/Request.py +++ b/module/network/Request.py @@ -24,6 +24,9 @@ from cStringIO import StringIO retrieveUrl returns response as string """ +class AbortDownload(Exception): + pass + class Request: def __init__(self): @@ -33,6 +36,8 @@ class Request: self.dl_arrived = 0 self.dl = False + self.abort = False + self.cookies = [] self.lastURL = None self.cj = cookielib.CookieJar() @@ -146,6 +151,7 @@ class Request: self.dl_arrived = 0 self.dl_time = time.time() for chunk in conn: + if self.abort: raise AbortDownload self.dl_arrived += len(chunk) file.write(chunk) file.close() diff --git a/module/thread_list.py b/module/thread_list.py index 1dadb91d3..52b264648 100644 --- a/module/thread_list.py +++ b/module/thread_list.py @@ -99,18 +99,19 @@ class Thread_List(object): self.list.remove(pyfile) if pyfile.plugin.props['type'] == "container": - self.list.extend(pyfile.plugin.links) - - if pyfile.status.type == "reconnected":#put it back in queque + elif pyfile.status.type == "reconnected":#put it back in queque self.list.files.insert(0, pyfile) - if pyfile.status.type == "failed": + elif pyfile.status.type == "failed": self.parent.logger.warning("Download failed: " + pyfile.url+" | "+ pyfile.status.error) with open(self.parent.config['failed_file'], 'a') as f: f.write(pyfile.url + "\n") + self.list.remove(pyfile) + elif pyfile.status.type == "aborted": + self.parent.logger.info("Download aborted: " + pyfile.url) self.list.remove(pyfile) self.list.save() diff --git a/pyLoadCli.py b/pyLoadCli.py index 378b97de9..bd13206ac 100644 --- a/pyLoadCli.py +++ b/pyLoadCli.py @@ -1,3 +1,4 @@ +import os.path #!/usr/bin/env python # -*- coding: utf-8 -*- # @@ -28,7 +29,7 @@ class pyLoadCli: self.thread = SocketThread(adress, int(port), pw, self) self.getch = _Getch() self.input = "" - self.pos = [0,0] + self.pos = [0, 0] self.inputline = 0 self.menuline = 0 @@ -76,10 +77,10 @@ class pyLoadCli: def print_input(self): self.println(self.inputline, white(" Input: ") + self.input) - self.println(self.inputline+1, "") - self.println(self.inputline+2, "") - self.println(self.inputline+3, "") - self.println(self.inputline+4, "") + self.println(self.inputline + 1, "") + self.println(self.inputline + 2, "") + self.println(self.inputline + 3, "") + self.println(self.inputline + 4, "") def data_arrived(self, obj): """Handle incoming data""" @@ -98,7 +99,7 @@ class pyLoadCli: speed += download['speed'] self.println(line, cyan(download["name"])) line += 1 - self.println(line, blue("[") + yellow(z * "#" + (25-z) * " ") + blue("] ") + green(str(percent) + "%") + " Speed: " + green(str(int(download['speed'])) + " kb/s") + " Finished in: " + green(self.format_time(download['eta']))) + self.println(line, blue("[") + yellow(z * "#" + (25-z) * " ") + blue("] ") + green(str(percent) + "%") + " Speed: " + green(str(int(download['speed'])) + " kb/s") + " Finished in: " + green(self.format_time(download['eta'])) + " ID: " + green(str(download['id']))) line += 1 if download["status"] == "waiting": self.println(line, cyan(download["name"])) @@ -107,7 +108,10 @@ class pyLoadCli: line += 1 self.println(line, "") line += 1 - self.println(line, "Status: " + red("paused") if obj.status['pause'] else "Status: " + red("running") + " total Speed: " + red(str(int(speed)) + " kb/s") + " Files in queue: " + red(str(obj.status["queue"]))) + if obj.status['pause']: + self.println(line, "Status: " + red("paused") + " total Speed: " + red(str(int(speed)) + " kb/s") + " Files in queue: " + red(str(obj.status["queue"]))) + else: + self.println(line, "Status: " + red("running") + " total Speed: " + red(str(int(speed)) + " kb/s") + " Files in queue: " + red(str(obj.status["queue"]))) line += 1 self.println(line, "") line += 1 @@ -128,7 +132,7 @@ class pyLoadCli: line += 1 self.println(line, mag("2.") + " Remove Links") line += 1 - self.println(line, mag("3.") + " Pause Server") + self.println(line, mag("3.") + " (Un)Pause Server") line += 1 self.println(line, mag("4.") + " Kill Server") line += 1 @@ -157,18 +161,18 @@ class pyLoadCli: self.println(line, "Type the number of the link you want to delete.") line += 1 i = 0 - for id in range(self.pos[1],self.pos[1]+5): - if id < 0 or id >= len(self.file_list['order']): - continue - item = self.file_list['order'][id] - self.println(line, mag(str(item)) + ": " + self.file_list[item].url) - line += 1 - i += 1 + for id in range(self.pos[1], self.pos[1] + 5): + if id < 0 or id >= len(self.file_list['order']): + continue + item = self.file_list['order'][id] + self.println(line, mag(str(item)) + ": " + self.file_list[item].url) + line += 1 + i += 1 for x in range(5-i): - self.println(line,"") + self.println(line, "") line += 1 - self.println(line, mag("p") +" - previous" + " | " + mag("n") + " - next") + self.println(line, mag("p") + " - previous" + " | " + mag("n") + " - next") line += 1 self.println(line, mag("0.") + " back to main menu") @@ -178,7 +182,7 @@ class pyLoadCli: def handle_input(self): inp = self.input if inp == "0": - self.pos = [0,0] + self.pos = [0, 0] self.build_menu() return True @@ -190,14 +194,15 @@ class pyLoadCli: self.pos[0] = 2 self.pos[1] = 0 elif inp == "3": - self.pos[0] = 3 + self.thread.push_exec("toggle_pause") elif inp == "4": - self.pos[0] = 4 + self.thread.push_exec("kill") + sys.exit() elif inp == "5": os.system('clear') sys.exit() elif self.pos[0] == 1: #add links - if inp[:7] == "http://": + if inp[:7] == "http://" or os.path.exists(inp): self.thread.push_exec("add_links", [(inp, None)]) self.links_added += 1 elif self.pos[0] == 2: #remove links @@ -211,12 +216,18 @@ class pyLoadCli: self.build_menu() class _Getch: - """Gets a single character from standard input. Does not echo to the screen.""" + """ + Gets a single character from standard input. Does not echo to + the screen. + """ def __init__(self): try: self.impl = _GetchWindows() except ImportError: - self.impl = _GetchUnix() + try: + self.impl = _GetchMacCarbon() + except(AttributeError, ImportError): + self.impl = _GetchUnix() def __call__(self): return self.impl() @@ -249,6 +260,37 @@ class _GetchWindows: import msvcrt return msvcrt.getch() +class _GetchMacCarbon: + """ + A function which returns the current ASCII key that is down; + if no ASCII key is down, the null string is returned. The + page http://www.mactech.com/macintosh-c/chap02-1.html was + very helpful in figuring out how to do this. + """ + def __init__(self): + import Carbon + Carbon.Evt #see if it has this (in Unix, it doesn't) + + def __call__(self): + import Carbon + if Carbon.Evt.EventAvail(0x0008)[0] == 0: # 0x0008 is the keyDownMask + return '' + else: + # + # The event contains the following info: + # (what,msg,when,where,mod)=Carbon.Evt.GetNextEvent(0x0008)[1] + # + # The message (msg) contains the ASCII char which is + # extracted with the 0x000000FF charCodeMask; this + # number is converted to an ASCII character with chr() and + # returned + # + (what, msg, when, where, mod) = Carbon.Evt.GetNextEvent(0x0008)[1] + return chr(msg) + + + + def blue(string): return "\033[1;34m" + string + "\033[0m" @@ -272,12 +314,10 @@ def white(string): if __name__ == "__main__": if len(sys.argv) != 4: - #address = raw_input("Adress:") - #port = raw_input("Port:") - #password = raw_input("Password:") - address = "localhost" - port = "7272" - password = "pwhere" + address = raw_input("Adress:") + port = raw_input("Port:") + password = raw_input("Password:") + cli = pyLoadCli(address, port, password) else: - cli = pyLoadCli( * sys.argv[1:]) + cli = pyLoadCli(* sys.argv[1:]) diff --git a/pyLoadCore.py b/pyLoadCore.py index e9d933dc6..3f45ca332 100644 --- a/pyLoadCore.py +++ b/pyLoadCore.py @@ -50,6 +50,8 @@ class Core(object): self.read_config() + self.do_kill = False + translation = gettext.translation("pyLoad", "locale", languages=[self.config['language']]) translation.install(unicode=True) @@ -219,6 +221,7 @@ class Core(object): self._test_print_status() self.server_test() sleep(2) + if self.do_kill: exit() def server_test(self): obj = RequestObject() @@ -238,12 +241,17 @@ class Core(object): self.server.start() def kill(self): + self.do_kill = True exit() + return True def shutdown(self): - + "abort all downloads and exit" self.thread_list.pause = True + for pyfile in self.thread_list.py_downloading: + pyfile.plugin.req.abort = True + while self.thread_list.py_downloading: sleep(1) @@ -261,6 +269,14 @@ class Core(object): def get_links(self): return self.file_list.data + def toggle_pause(self): + if self.thread_list.pause: + self.thread_list.pause = False + return False + elif not self.thread_list.pause: + self.thread_list.pause = True + return True + if __name__ == "__main__": testLoader = Core() testLoader.start() |